@vertesia/ui 0.67.0 → 0.69.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/lib/esm/core/components/Badge.js +1 -1
- package/lib/esm/core/components/Badge.js.map +1 -1
- package/lib/esm/core/components/FormItem.js +2 -2
- package/lib/esm/core/components/FormItem.js.map +1 -1
- package/lib/esm/core/components/InputList.js +2 -2
- package/lib/esm/core/components/InputList.js.map +1 -1
- package/lib/esm/core/components/shadcn/checkbox.js +1 -1
- package/lib/esm/core/components/shadcn/checkbox.js.map +1 -1
- package/lib/esm/core/components/shadcn/command.js +1 -1
- package/lib/esm/core/components/shadcn/command.js.map +1 -1
- package/lib/esm/core/components/shadcn/dialog.js +6 -6
- package/lib/esm/core/components/shadcn/dialog.js.map +1 -1
- package/lib/esm/core/components/shadcn/filters/DynamicLabel.js.map +1 -1
- package/lib/esm/core/components/shadcn/filters/comboBox/DateCombobox.js +129 -0
- package/lib/esm/core/components/shadcn/filters/comboBox/DateCombobox.js.map +1 -0
- package/lib/esm/core/components/shadcn/filters/comboBox/SelectCombobox.js +46 -0
- package/lib/esm/core/components/shadcn/filters/comboBox/SelectCombobox.js.map +1 -0
- package/lib/esm/core/components/shadcn/filters/comboBox/StringListCombobox.js +23 -0
- package/lib/esm/core/components/shadcn/filters/comboBox/StringListCombobox.js.map +1 -0
- package/lib/esm/core/components/shadcn/filters/comboBox/TextCombobox.js +28 -0
- package/lib/esm/core/components/shadcn/filters/comboBox/TextCombobox.js.map +1 -0
- package/lib/esm/core/components/shadcn/filters/comboBox/comboBox.js +5 -0
- package/lib/esm/core/components/shadcn/filters/comboBox/comboBox.js.map +1 -0
- package/lib/esm/core/components/shadcn/filters/filter/SelectFilter.js +101 -0
- package/lib/esm/core/components/shadcn/filters/filter/SelectFilter.js.map +1 -0
- package/lib/esm/core/components/shadcn/filters/{stringListFilter.js → filter/StringListFilter.js} +3 -3
- package/lib/esm/core/components/shadcn/filters/filter/StringListFilter.js.map +1 -0
- package/lib/esm/core/components/shadcn/filters/{textFilter.js → filter/TextFilter.js} +4 -4
- package/lib/esm/core/components/shadcn/filters/filter/TextFilter.js.map +1 -0
- package/lib/esm/core/components/shadcn/filters/filter/dateFilter.js +161 -0
- package/lib/esm/core/components/shadcn/filters/filter/dateFilter.js.map +1 -0
- package/lib/esm/core/components/shadcn/filters/filter-styles.js +88 -0
- package/lib/esm/core/components/shadcn/filters/filter-styles.js.map +1 -0
- package/lib/esm/core/components/shadcn/filters/filterBar.js +128 -87
- package/lib/esm/core/components/shadcn/filters/filterBar.js.map +1 -1
- package/lib/esm/core/components/shadcn/filters/filters.js +7 -6
- package/lib/esm/core/components/shadcn/filters/filters.js.map +1 -1
- package/lib/esm/core/components/shadcn/filters/index.js +1 -1
- package/lib/esm/core/components/shadcn/filters/index.js.map +1 -1
- package/lib/esm/core/components/shadcn/filters/types.js.map +1 -1
- package/lib/esm/core/components/toast/NotificationPanel.js +24 -18
- package/lib/esm/core/components/toast/NotificationPanel.js.map +1 -1
- package/lib/esm/features/agent/PayloadBuilder.js +47 -27
- package/lib/esm/features/agent/PayloadBuilder.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentConversation.js +9 -3
- package/lib/esm/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +7 -6
- package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/MessageItem.js +12 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/SlidingMessages.js +2 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/SlidingMessages.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/utils.js +10 -4
- package/lib/esm/features/agent/chat/ModernAgentOutput/utils.js.map +1 -1
- package/lib/esm/features/facets/DocumentsFacetsNav.js +133 -0
- package/lib/esm/features/facets/DocumentsFacetsNav.js.map +1 -0
- package/lib/esm/features/facets/RunsFacetsNav.js +125 -0
- package/lib/esm/features/facets/RunsFacetsNav.js.map +1 -0
- package/lib/esm/features/facets/VFacetsNav.js +4 -113
- package/lib/esm/features/facets/VFacetsNav.js.map +1 -1
- package/lib/esm/features/facets/VStringFacet.js +6 -4
- package/lib/esm/features/facets/VStringFacet.js.map +1 -1
- package/lib/esm/features/facets/VTypeFacet.js +4 -5
- package/lib/esm/features/facets/VTypeFacet.js.map +1 -1
- package/lib/esm/features/facets/VUserFacet.js +1 -1
- package/lib/esm/features/facets/VUserFacet.js.map +1 -1
- package/lib/esm/features/facets/WorkflowExecutionsFacetsNav.js +98 -0
- package/lib/esm/features/facets/WorkflowExecutionsFacetsNav.js.map +1 -0
- package/lib/esm/features/facets/index.js +3 -2
- package/lib/esm/features/facets/index.js.map +1 -1
- package/lib/esm/features/store/collections/CollectionsTable.js +1 -1
- package/lib/esm/features/store/collections/CollectionsTable.js.map +1 -1
- package/lib/esm/features/store/collections/CreateCollection.js +10 -9
- package/lib/esm/features/store/collections/CreateCollection.js.map +1 -1
- package/lib/esm/features/store/collections/EditCollectionView.js +10 -9
- package/lib/esm/features/store/collections/EditCollectionView.js.map +1 -1
- package/lib/esm/features/store/collections/SelectCollection.js +1 -1
- package/lib/esm/features/store/collections/SelectCollection.js.map +1 -1
- package/lib/esm/features/store/objects/DocumentPreviewPanel.js +0 -1
- package/lib/esm/features/store/objects/DocumentPreviewPanel.js.map +1 -1
- package/lib/esm/features/store/objects/DocumentSearchResults.js +37 -2
- package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
- package/lib/esm/features/store/objects/components/ContentOverview.js +0 -2
- package/lib/esm/features/store/objects/components/ContentOverview.js.map +1 -1
- package/lib/esm/features/store/objects/components/SelectDocument.js +2 -2
- package/lib/esm/features/store/objects/components/SelectDocument.js.map +1 -1
- package/lib/esm/features/store/objects/components/VectorSearchWidget.js +1 -1
- package/lib/esm/features/store/objects/components/VectorSearchWidget.js.map +1 -1
- package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js +16 -4
- package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js.map +1 -1
- package/lib/esm/features/store/objects/upload/DocumentUploadModal.js +72 -37
- package/lib/esm/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
- package/lib/esm/features/store/types/ObjectSchemaEditor.js +15 -0
- package/lib/esm/features/store/types/ObjectSchemaEditor.js.map +1 -1
- package/lib/esm/features/user/UserInfo.js +8 -8
- package/lib/esm/features/user/UserInfo.js.map +1 -1
- package/lib/esm/router/HistoryNavigator.js +2 -2
- package/lib/esm/router/HistoryNavigator.js.map +1 -1
- package/lib/esm/shell/SplashScreen.js +19 -0
- package/lib/esm/shell/SplashScreen.js.map +1 -0
- package/lib/esm/shell/VertesiaShell.js +10 -0
- package/lib/esm/shell/VertesiaShell.js.map +1 -0
- package/lib/esm/shell/index.js +7 -0
- package/lib/esm/shell/index.js.map +1 -0
- package/lib/esm/shell/login/EnterpriseSigninButton.js +81 -0
- package/lib/esm/shell/login/EnterpriseSigninButton.js.map +1 -0
- package/lib/esm/shell/login/GitHubSignInButton.js +24 -0
- package/lib/esm/shell/login/GitHubSignInButton.js.map +1 -0
- package/lib/esm/shell/login/GoogleSignInButton.js +25 -0
- package/lib/esm/shell/login/GoogleSignInButton.js.map +1 -0
- package/lib/esm/shell/login/InviteAcceptModal.js +45 -0
- package/lib/esm/shell/login/InviteAcceptModal.js.map +1 -0
- package/lib/esm/shell/login/MicrosoftSigninButton.js +19 -0
- package/lib/esm/shell/login/MicrosoftSigninButton.js.map +1 -0
- package/lib/esm/shell/login/PreviewIcon.js +23 -0
- package/lib/esm/shell/login/PreviewIcon.js.map +1 -0
- package/lib/esm/shell/login/SignInModal.js +9 -0
- package/lib/esm/shell/login/SignInModal.js.map +1 -0
- package/lib/esm/shell/login/SigninScreen.js +64 -0
- package/lib/esm/shell/login/SigninScreen.js.map +1 -0
- package/lib/esm/shell/login/SignupForm.js +91 -0
- package/lib/esm/shell/login/SignupForm.js.map +1 -0
- package/lib/esm/shell/login/TerminalLogin.js +179 -0
- package/lib/esm/shell/login/TerminalLogin.js.map +1 -0
- package/lib/esm/shell/login/UserInfo.js +40 -0
- package/lib/esm/shell/login/UserInfo.js.map +1 -0
- package/lib/esm/shell/login/UserSessionMenu.js +31 -0
- package/lib/esm/shell/login/UserSessionMenu.js.map +1 -0
- package/lib/esm/shell/utils.js +6 -0
- package/lib/esm/shell/utils.js.map +1 -0
- package/lib/esm/widgets/SvgIcon.js +36 -0
- package/lib/esm/widgets/SvgIcon.js.map +1 -0
- package/lib/esm/widgets/index.js +7 -6
- package/lib/esm/widgets/index.js.map +1 -1
- package/lib/esm/widgets/upload/UploadSummary.js +1 -1
- package/lib/esm/widgets/upload/UploadSummary.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/core/components/FormItem.d.ts +2 -1
- package/lib/types/core/components/shadcn/dialog.d.ts +2 -1
- package/lib/types/core/components/shadcn/filters/DynamicLabel.d.ts +1 -1
- package/lib/types/core/components/shadcn/filters/comboBox/DateCombobox.d.ts +5 -0
- package/lib/types/core/components/shadcn/filters/comboBox/SelectCombobox.d.ts +8 -0
- package/lib/types/core/components/shadcn/filters/comboBox/StringListCombobox.d.ts +5 -0
- package/lib/types/core/components/shadcn/filters/comboBox/TextCombobox.d.ts +5 -0
- package/lib/types/core/components/shadcn/filters/comboBox/comboBox.d.ts +4 -0
- package/lib/types/core/components/shadcn/filters/{selectFilter.d.ts → filter/SelectFilter.d.ts} +2 -2
- package/lib/types/core/components/shadcn/filters/{stringListFilter.d.ts → filter/StringListFilter.d.ts} +1 -1
- package/lib/types/core/components/shadcn/filters/{textFilter.d.ts → filter/TextFilter.d.ts} +1 -1
- package/lib/types/core/components/shadcn/filters/{dateFilter.d.ts → filter/dateFilter.d.ts} +1 -1
- package/lib/types/core/components/shadcn/filters/filter-styles.d.ts +1 -0
- package/lib/types/core/components/shadcn/filters/filterBar.d.ts +14 -4
- package/lib/types/core/components/shadcn/filters/index.d.ts +1 -1
- package/lib/types/core/components/shadcn/filters/types.d.ts +2 -0
- package/lib/types/features/agent/PayloadBuilder.d.ts +17 -8
- package/lib/types/features/agent/chat/ModernAgentOutput/utils.d.ts +2 -1
- package/lib/types/features/facets/DocumentsFacetsNav.d.ts +16 -0
- package/lib/types/features/facets/RunsFacetsNav.d.ts +18 -0
- package/lib/types/features/facets/VFacetsNav.d.ts +1 -1
- package/lib/types/features/facets/VStringFacet.d.ts +6 -2
- package/lib/types/features/facets/VTypeFacet.d.ts +3 -1
- package/lib/types/features/facets/WorkflowExecutionsFacetsNav.d.ts +13 -0
- package/lib/types/features/facets/index.d.ts +3 -2
- package/lib/types/shell/SplashScreen.d.ts +4 -0
- package/lib/types/shell/VertesiaShell.d.ts +7 -0
- package/lib/types/shell/index.d.ts +6 -0
- package/lib/types/shell/login/EnterpriseSigninButton.d.ts +5 -0
- package/lib/types/shell/login/GitHubSignInButton.d.ts +5 -0
- package/lib/types/shell/login/GoogleSignInButton.d.ts +5 -0
- package/lib/types/shell/login/InviteAcceptModal.d.ts +1 -0
- package/lib/types/shell/login/MicrosoftSigninButton.d.ts +5 -0
- package/lib/types/shell/login/PreviewIcon.d.ts +5 -0
- package/lib/types/shell/login/SignInModal.d.ts +6 -0
- package/lib/types/shell/login/SigninScreen.d.ts +8 -0
- package/lib/types/shell/login/SignupForm.d.ts +7 -0
- package/lib/types/shell/login/TerminalLogin.d.ts +1 -0
- package/lib/types/shell/login/UserInfo.d.ts +5 -0
- package/lib/types/shell/login/UserSessionMenu.d.ts +8 -0
- package/lib/types/shell/utils.d.ts +1 -0
- package/lib/types/widgets/SvgIcon.d.ts +6 -0
- package/lib/types/widgets/index.d.ts +7 -6
- package/lib/vertesia-ui-core.js +1 -1
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-features.js +1 -1
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-router.js +1 -1
- package/lib/vertesia-ui-router.js.map +1 -1
- package/lib/vertesia-ui-shell.js +2 -0
- package/lib/vertesia-ui-shell.js.map +1 -0
- package/lib/vertesia-ui-widgets.js +1 -1
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/package.json +14 -6
- package/src/core/components/Badge.tsx +12 -8
- package/src/core/components/FormItem.tsx +4 -3
- package/src/core/components/InputList.tsx +21 -17
- package/src/core/components/shadcn/checkbox.tsx +2 -2
- package/src/core/components/shadcn/command.tsx +1 -1
- package/src/core/components/shadcn/dialog.tsx +18 -9
- package/src/core/components/shadcn/filters/DynamicLabel.tsx +1 -2
- package/src/core/components/shadcn/filters/comboBox/DateCombobox.tsx +211 -0
- package/src/core/components/shadcn/filters/{comboBox.tsx → comboBox/SelectCombobox.tsx} +8 -192
- package/src/core/components/shadcn/filters/comboBox/StringListCombobox.tsx +76 -0
- package/src/core/components/shadcn/filters/comboBox/TextCombobox.tsx +81 -0
- package/src/core/components/shadcn/filters/comboBox/comboBox.tsx +4 -0
- package/src/core/components/shadcn/filters/filter/SelectFilter.tsx +161 -0
- package/src/core/components/shadcn/filters/{stringListFilter.tsx → filter/StringListFilter.tsx} +7 -7
- package/src/core/components/shadcn/filters/{textFilter.tsx → filter/TextFilter.tsx} +17 -11
- package/src/core/components/shadcn/filters/filter/dateFilter.tsx +256 -0
- package/src/core/components/shadcn/filters/filter-styles.ts +87 -0
- package/src/core/components/shadcn/filters/filterBar.tsx +208 -152
- package/src/core/components/shadcn/filters/filters.tsx +7 -5
- package/src/core/components/shadcn/filters/index.ts +1 -1
- package/src/core/components/shadcn/filters/types.ts +2 -0
- package/src/core/components/toast/NotificationPanel.tsx +38 -22
- package/src/features/agent/PayloadBuilder.tsx +56 -31
- package/src/features/agent/chat/ModernAgentConversation.tsx +10 -4
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +7 -6
- package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +12 -1
- package/src/features/agent/chat/ModernAgentOutput/SlidingMessages.tsx +2 -1
- package/src/features/agent/chat/ModernAgentOutput/utils.ts +12 -4
- package/src/features/facets/DocumentsFacetsNav.tsx +171 -0
- package/src/features/facets/RunsFacetsNav.tsx +166 -0
- package/src/features/facets/VFacetsNav.tsx +10 -126
- package/src/features/facets/VStringFacet.tsx +10 -4
- package/src/features/facets/VTypeFacet.tsx +6 -5
- package/src/features/facets/VUserFacet.tsx +5 -3
- package/src/features/facets/WorkflowExecutionsFacetsNav.tsx +132 -0
- package/src/features/facets/index.ts +5 -2
- package/src/features/store/collections/CollectionsTable.tsx +3 -2
- package/src/features/store/collections/CreateCollection.tsx +17 -15
- package/src/features/store/collections/EditCollectionView.tsx +19 -16
- package/src/features/store/collections/SelectCollection.tsx +1 -1
- package/src/features/store/objects/DocumentPreviewPanel.tsx +0 -1
- package/src/features/store/objects/DocumentSearchResults.tsx +80 -11
- package/src/features/store/objects/components/ContentOverview.tsx +0 -2
- package/src/features/store/objects/components/SelectDocument.tsx +2 -2
- package/src/features/store/objects/components/VectorSearchWidget.tsx +2 -2
- package/src/features/store/objects/selection/actions/AddToCollectionAction.tsx +40 -19
- package/src/features/store/objects/upload/DocumentUploadModal.tsx +160 -214
- package/src/features/store/types/ObjectSchemaEditor.tsx +15 -0
- package/src/features/user/UserInfo.tsx +17 -14
- package/src/router/HistoryNavigator.ts +2 -2
- package/src/shell/SplashScreen.tsx +41 -0
- package/src/shell/VertesiaShell.tsx +27 -0
- package/src/shell/index.tsx +6 -0
- package/src/shell/login/EnterpriseSigninButton.tsx +106 -0
- package/src/shell/login/GitHubSignInButton.tsx +40 -0
- package/src/shell/login/GoogleSignInButton.tsx +36 -0
- package/src/shell/login/InviteAcceptModal.tsx +78 -0
- package/src/shell/login/MicrosoftSigninButton.tsx +30 -0
- package/src/shell/login/PreviewIcon.tsx +29 -0
- package/src/shell/login/SignInModal.tsx +28 -0
- package/src/shell/login/SigninScreen.tsx +162 -0
- package/src/shell/login/SignupForm.tsx +178 -0
- package/src/shell/login/TerminalLogin.tsx +299 -0
- package/src/shell/login/UserInfo.tsx +76 -0
- package/src/shell/login/UserSessionMenu.tsx +81 -0
- package/src/shell/utils.tsx +7 -0
- package/src/widgets/SvgIcon.tsx +44 -0
- package/src/widgets/index.ts +7 -6
- package/src/widgets/upload/UploadSummary.tsx +3 -4
- package/lib/esm/core/components/shadcn/filters/comboBox.js +0 -101
- package/lib/esm/core/components/shadcn/filters/comboBox.js.map +0 -1
- package/lib/esm/core/components/shadcn/filters/dateFilter.js +0 -36
- package/lib/esm/core/components/shadcn/filters/dateFilter.js.map +0 -1
- package/lib/esm/core/components/shadcn/filters/selectFilter.js +0 -67
- package/lib/esm/core/components/shadcn/filters/selectFilter.js.map +0 -1
- package/lib/esm/core/components/shadcn/filters/stringListFilter.js.map +0 -1
- package/lib/esm/core/components/shadcn/filters/textFilter.js.map +0 -1
- package/lib/esm/features/facets/InteractionFacet.js +0 -39
- package/lib/esm/features/facets/InteractionFacet.js.map +0 -1
- package/lib/esm/features/facets/TypeOptions.js +0 -19
- package/lib/esm/features/facets/TypeOptions.js.map +0 -1
- package/lib/esm/features/facets/UserFacet.js +0 -33
- package/lib/esm/features/facets/UserFacet.js.map +0 -1
- package/lib/types/core/components/shadcn/filters/comboBox.d.ts +0 -22
- package/lib/types/features/facets/InteractionFacet.d.ts +0 -9
- package/lib/types/features/facets/TypeOptions.d.ts +0 -3
- package/lib/types/features/facets/UserFacet.d.ts +0 -11
- package/src/core/components/shadcn/filters/dateFilter.tsx +0 -82
- package/src/core/components/shadcn/filters/selectFilter.tsx +0 -110
- package/src/features/facets/InteractionFacet.tsx +0 -53
- package/src/features/facets/TypeOptions.tsx +0 -22
- package/src/features/facets/UserFacet.tsx +0 -61
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Collection, ContentObjectTypeItem, DynamicCollection } from "@vertesia/common";
|
|
2
|
-
import { Button,
|
|
2
|
+
import { Button, MessageBox, VModal, VModalBody, VModalFooter, VModalTitle, VSelectBox, Spinner, useToast, VTooltip } from "@vertesia/ui/core";
|
|
3
3
|
import { useUserSession } from "@vertesia/ui/session";
|
|
4
4
|
import { DropZone, UploadSummary } from '@vertesia/ui/widgets';
|
|
5
|
-
import { AlertCircleIcon, CheckCircleIcon, FileIcon, FolderIcon, UploadIcon, XCircleIcon } from "lucide-react";
|
|
5
|
+
import { AlertCircleIcon, CheckCircleIcon, FileIcon, FolderIcon, Info, UploadIcon, XCircleIcon } from "lucide-react";
|
|
6
6
|
import { ReactNode, useEffect, useMemo, useState } from "react";
|
|
7
7
|
import { FileUploadAction, FileWithMetadata, useSmartFileUploadProcessing } from "./useSmartFileUploadProcessing";
|
|
8
8
|
import { DocumentUploadResult } from "./useUploadHandler";
|
|
@@ -79,6 +79,9 @@ export function DocumentUploadModal({
|
|
|
79
79
|
const [overallProgress, setOverallProgress] = useState(0);
|
|
80
80
|
const [modalKey, setModalKey] = useState(Date.now());
|
|
81
81
|
const [collectionData, setCollectionData] = useState<Collection | DynamicCollection | undefined>(undefined);
|
|
82
|
+
const [result, setResult] = useState<DocumentUploadResult | null>(null);
|
|
83
|
+
const [_title, setTitle] = useState(title);
|
|
84
|
+
const [_description, setDescription] = useState("");
|
|
82
85
|
|
|
83
86
|
// Fetch collection details if a collectionId is provided
|
|
84
87
|
useEffect(() => {
|
|
@@ -86,17 +89,37 @@ export function DocumentUploadModal({
|
|
|
86
89
|
client.store.collections.retrieve(collectionId).then(setCollectionData);
|
|
87
90
|
}, [collectionId]);
|
|
88
91
|
|
|
92
|
+
// Update title and description based on current state
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
if (isUploading) {
|
|
95
|
+
setTitle("Uploading Files");
|
|
96
|
+
setDescription(`${Math.round(overallProgress)}% complete`);
|
|
97
|
+
} else if (uploadComplete) {
|
|
98
|
+
setTitle("Upload Complete");
|
|
99
|
+
setDescription("");
|
|
100
|
+
} else if (processingDone) {
|
|
101
|
+
setTitle("File Analysis Results");
|
|
102
|
+
setDescription(`${files.length} file${files.length !== 1 ? "s" : ""}`);
|
|
103
|
+
} else if (files.length > 0) {
|
|
104
|
+
setTitle(title);
|
|
105
|
+
setDescription("Checking for duplicates and updates");
|
|
106
|
+
} else {
|
|
107
|
+
setTitle(title);
|
|
108
|
+
setDescription("");
|
|
109
|
+
}
|
|
110
|
+
}, [isUploading, uploadComplete, processingDone, title, overallProgress, files.length]);
|
|
111
|
+
|
|
89
112
|
// Helper function to render collection and folder information
|
|
90
113
|
const renderLocationInfo = () => {
|
|
91
114
|
if (!collectionData && !selectedFolder) return null;
|
|
92
115
|
|
|
93
116
|
return (
|
|
94
|
-
<div className="mb-4 p-3 bg-
|
|
95
|
-
<div className="flex items-center text-
|
|
96
|
-
<FolderIcon className="
|
|
117
|
+
<div className="mb-4 p-3 bg-primary rounded-md border border-primary">
|
|
118
|
+
<div className="flex items-center text-primary">
|
|
119
|
+
<FolderIcon className="size-5 mr-2" />
|
|
97
120
|
<span className="font-medium">Upload Location:</span>
|
|
98
121
|
</div>
|
|
99
|
-
<div className="ml-7 text-sm text-
|
|
122
|
+
<div className="ml-7 text-sm text-primary mt-1">
|
|
100
123
|
{collectionData && (
|
|
101
124
|
<div className="flex items-center">
|
|
102
125
|
<span className="mr-1">Collection:</span>
|
|
@@ -132,21 +155,25 @@ export function DocumentUploadModal({
|
|
|
132
155
|
// Reset state when modal opens/closes
|
|
133
156
|
useEffect(() => {
|
|
134
157
|
if (isOpen) {
|
|
158
|
+
// Always reset state first
|
|
159
|
+
setProcessedFiles([]);
|
|
160
|
+
setProcessingDone(false);
|
|
161
|
+
setSelectedType(null);
|
|
162
|
+
setFileStatuses([]);
|
|
163
|
+
setIsUploading(false);
|
|
164
|
+
setUploadComplete(false);
|
|
165
|
+
setOverallProgress(0);
|
|
166
|
+
setProcessingStats({ toCreate: 0, toUpdate: 0, toSkip: 0 });
|
|
167
|
+
setResult(null);
|
|
168
|
+
setTitle(title);
|
|
169
|
+
setDescription("");
|
|
170
|
+
|
|
135
171
|
// Set initial files if provided
|
|
136
172
|
if (initialFiles && initialFiles.length > 0) {
|
|
137
173
|
setFiles(initialFiles);
|
|
138
174
|
processFiles(initialFiles);
|
|
139
175
|
} else {
|
|
140
|
-
// Reset state
|
|
141
176
|
setFiles([]);
|
|
142
|
-
setProcessedFiles([]);
|
|
143
|
-
setProcessingDone(false);
|
|
144
|
-
setSelectedType(null);
|
|
145
|
-
setFileStatuses([]);
|
|
146
|
-
setIsUploading(false);
|
|
147
|
-
setUploadComplete(false);
|
|
148
|
-
setOverallProgress(0);
|
|
149
|
-
setProcessingStats({ toCreate: 0, toUpdate: 0, toSkip: 0 });
|
|
150
177
|
}
|
|
151
178
|
|
|
152
179
|
// Create a new key to ensure the modal is fresh
|
|
@@ -166,6 +193,10 @@ export function DocumentUploadModal({
|
|
|
166
193
|
setUploadComplete(false);
|
|
167
194
|
setOverallProgress(0);
|
|
168
195
|
setProcessingStats({ toCreate: 0, toUpdate: 0, toSkip: 0 });
|
|
196
|
+
setResult(null);
|
|
197
|
+
setTitle(title);
|
|
198
|
+
setDescription("");
|
|
199
|
+
setModalKey(Date.now());
|
|
169
200
|
|
|
170
201
|
// Call the provided onClose function
|
|
171
202
|
onClose();
|
|
@@ -511,11 +542,48 @@ export function DocumentUploadModal({
|
|
|
511
542
|
status: failedCount > 0 ? "warning" : "success",
|
|
512
543
|
duration: 5000,
|
|
513
544
|
});
|
|
545
|
+
setResult(result);
|
|
546
|
+
};
|
|
514
547
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
548
|
+
const typeSelection = () => {
|
|
549
|
+
return (
|
|
550
|
+
<div className="mb-4">
|
|
551
|
+
<label className="block text-sm font-medium mb-2">
|
|
552
|
+
Content Type <span className="text-muted font-normal">(Optional)</span>
|
|
553
|
+
<VTooltip
|
|
554
|
+
description="Select a content type to apply to the uploaded files. If left empty, Vertesia will automatically detect the type based on file content."
|
|
555
|
+
placement="top" size="xs"
|
|
556
|
+
>
|
|
557
|
+
<Info className="size-3 ml-2" />
|
|
558
|
+
</VTooltip>
|
|
559
|
+
</label>
|
|
560
|
+
<VSelectBox
|
|
561
|
+
options={types}
|
|
562
|
+
value={selectedType}
|
|
563
|
+
optionLabel={(type) => (type ? type.name : "Select a content type")}
|
|
564
|
+
placeholder="Select a content type or leave empty for automatic detection"
|
|
565
|
+
onChange={(selected) => setSelectedType(selected === undefined ? null : selected)}
|
|
566
|
+
filterBy="name"
|
|
567
|
+
isClearable
|
|
568
|
+
/>
|
|
569
|
+
{selectedType ? (
|
|
570
|
+
<></>
|
|
571
|
+
) : (
|
|
572
|
+
<div className="p-2 rounded-md">
|
|
573
|
+
<div className="flex items-center text-attention">
|
|
574
|
+
<CheckCircleIcon className="size-4 mr-1" />
|
|
575
|
+
Automatic Type Detection
|
|
576
|
+
<VTooltip
|
|
577
|
+
description="Vertesia will analyze the content and select the most appropriate type. This is recommended for most uploads and ensures optimal processing."
|
|
578
|
+
placement="top" size="xs"
|
|
579
|
+
>
|
|
580
|
+
<Info className="size-3 ml-2" />
|
|
581
|
+
</VTooltip>
|
|
582
|
+
</div>
|
|
583
|
+
</div>
|
|
584
|
+
)}
|
|
585
|
+
</div>
|
|
586
|
+
)
|
|
519
587
|
};
|
|
520
588
|
|
|
521
589
|
// Determine what content to show based on the current state
|
|
@@ -523,67 +591,22 @@ export function DocumentUploadModal({
|
|
|
523
591
|
// When showing only type selection, skip directly to the type selection UI
|
|
524
592
|
if (showTypeSelectionOnly) {
|
|
525
593
|
return (
|
|
526
|
-
<
|
|
594
|
+
<VModalBody>
|
|
527
595
|
{children}
|
|
528
596
|
|
|
529
597
|
{/* Collection and folder information if available */}
|
|
530
598
|
{renderLocationInfo()}
|
|
531
599
|
|
|
532
600
|
{/* Type selection */}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
Content Type <span className="text-gray-500 font-normal">(Optional)</span>
|
|
536
|
-
</label>
|
|
537
|
-
<SelectBox
|
|
538
|
-
options={types}
|
|
539
|
-
value={selectedType}
|
|
540
|
-
optionLabel={(type) => (type ? type.name : "Select a content type")}
|
|
541
|
-
placeholder="Select a content type or leave empty for automatic detection"
|
|
542
|
-
onChange={(selected) => setSelectedType(selected === undefined ? null : selected)}
|
|
543
|
-
filterBy="name"
|
|
544
|
-
isClearable
|
|
545
|
-
/>
|
|
546
|
-
|
|
547
|
-
<div className="mt-2 text-sm text-blue-600 flex items-center">
|
|
548
|
-
<CheckCircleIcon className="h-4 w-4 mr-1" />
|
|
549
|
-
<span>
|
|
550
|
-
<strong>Type selection is optional.</strong> Leave empty to let Vertesia choose the
|
|
551
|
-
appropriate type
|
|
552
|
-
</span>
|
|
553
|
-
</div>
|
|
554
|
-
</div>
|
|
555
|
-
|
|
556
|
-
{selectedType ? (
|
|
557
|
-
<div className="text-sm text-gray-500 bg-gray-50 p-3 rounded-md mb-4">
|
|
558
|
-
<div className="font-medium">{selectedType.name}</div>
|
|
559
|
-
{selectedType.description && <div className="mt-1">{selectedType.description}</div>}
|
|
560
|
-
</div>
|
|
561
|
-
) : (
|
|
562
|
-
<div className="text-sm text-blue-600 bg-blue-50 p-3 rounded-md mb-4">
|
|
563
|
-
<div className="font-medium flex items-center">
|
|
564
|
-
<CheckCircleIcon className="h-5 w-5 mr-1" />
|
|
565
|
-
Automatic Type Detection
|
|
566
|
-
</div>
|
|
567
|
-
<div className="mt-1">
|
|
568
|
-
<p>
|
|
569
|
-
<strong>
|
|
570
|
-
Vertesia will analyze the content and select the most appropriate type.
|
|
571
|
-
</strong>
|
|
572
|
-
</p>
|
|
573
|
-
<p className="mt-1">
|
|
574
|
-
This is recommended for most uploads and ensures optimal processing.
|
|
575
|
-
</p>
|
|
576
|
-
</div>
|
|
577
|
-
</div>
|
|
578
|
-
)}
|
|
579
|
-
</ModalBody>
|
|
601
|
+
{typeSelection()}
|
|
602
|
+
</VModalBody>
|
|
580
603
|
);
|
|
581
604
|
}
|
|
582
605
|
|
|
583
|
-
// Step 1: File selection
|
|
606
|
+
// Step 1: File selection #todo: update styles
|
|
584
607
|
if (files.length === 0 && !hideFileSelection) {
|
|
585
608
|
return (
|
|
586
|
-
<
|
|
609
|
+
<VModalBody className="flex flex-col items-center justify-center p-8">
|
|
587
610
|
{/* Collection and folder information if available */}
|
|
588
611
|
{renderLocationInfo()}
|
|
589
612
|
|
|
@@ -594,22 +617,19 @@ export function DocumentUploadModal({
|
|
|
594
617
|
className="w-full h-64"
|
|
595
618
|
/>
|
|
596
619
|
{children}
|
|
597
|
-
</
|
|
620
|
+
</VModalBody>
|
|
598
621
|
);
|
|
599
622
|
}
|
|
600
623
|
|
|
601
624
|
// Step 2: File processing and type selection
|
|
602
625
|
if (!isUploading && !uploadComplete) {
|
|
603
626
|
return (
|
|
604
|
-
<
|
|
627
|
+
<VModalBody>
|
|
605
628
|
{!processingDone ? (
|
|
606
629
|
// File processing in progress
|
|
607
|
-
<div className="flex flex-col items-center justify-center py-
|
|
630
|
+
<div className="flex flex-col items-center justify-center py-4">
|
|
608
631
|
<Spinner size="lg" className="mb-4" />
|
|
609
632
|
<div className="text-lg font-medium">Analyzing files...</div>
|
|
610
|
-
<div className="text-sm text-muted mt-2">
|
|
611
|
-
Checking for duplicates and updates
|
|
612
|
-
</div>
|
|
613
633
|
</div>
|
|
614
634
|
) : (
|
|
615
635
|
// Processing complete, show type selection
|
|
@@ -618,33 +638,26 @@ export function DocumentUploadModal({
|
|
|
618
638
|
{renderLocationInfo()}
|
|
619
639
|
|
|
620
640
|
<div className="mb-4">
|
|
621
|
-
<div className="flex justify-between items-center mb-2">
|
|
622
|
-
<div className="text-lg font-medium">File Analysis Results</div>
|
|
623
|
-
<div className="text-sm text-muted">
|
|
624
|
-
{files.length} file{files.length !== 1 ? "s" : ""}
|
|
625
|
-
</div>
|
|
626
|
-
</div>
|
|
627
|
-
|
|
628
641
|
{/* File statistics */}
|
|
629
|
-
<div className="
|
|
642
|
+
<div className="p-4 rounded-md mb-4">
|
|
630
643
|
<div className="grid grid-cols-3 gap-4">
|
|
631
644
|
<div className="flex flex-col items-center">
|
|
632
|
-
<div className="flex items-center">
|
|
633
|
-
<UploadIcon className="
|
|
645
|
+
<div className="flex items-center gap-2">
|
|
646
|
+
<UploadIcon className="size-5 text-primary" />
|
|
634
647
|
<span className="font-medium">New</span>
|
|
635
648
|
</div>
|
|
636
649
|
<div className="text-2xl font-semibold">{processingStats.toCreate}</div>
|
|
637
650
|
</div>
|
|
638
651
|
<div className="flex flex-col items-center">
|
|
639
|
-
<div className="flex items-center">
|
|
640
|
-
<CheckCircleIcon className="
|
|
652
|
+
<div className="flex items-center gap-2">
|
|
653
|
+
<CheckCircleIcon className="size-5 text-success" />
|
|
641
654
|
<span className="font-medium">Update</span>
|
|
642
655
|
</div>
|
|
643
656
|
<div className="text-2xl font-semibold">{processingStats.toUpdate}</div>
|
|
644
657
|
</div>
|
|
645
658
|
<div className="flex flex-col items-center">
|
|
646
|
-
<div className="flex items-center">
|
|
647
|
-
<AlertCircleIcon className="
|
|
659
|
+
<div className="flex items-center gap-2">
|
|
660
|
+
<AlertCircleIcon className="size-5 text-mixer-attention/40" />
|
|
648
661
|
<span className="font-medium">Skip</span>
|
|
649
662
|
</div>
|
|
650
663
|
<div className="text-2xl font-semibold">{processingStats.toSkip}</div>
|
|
@@ -654,120 +667,51 @@ export function DocumentUploadModal({
|
|
|
654
667
|
</div>
|
|
655
668
|
|
|
656
669
|
{/* Type selection */}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
670
|
+
{typeSelection()}
|
|
671
|
+
|
|
672
|
+
<MessageBox
|
|
673
|
+
className="mb-4"
|
|
674
|
+
status="info"
|
|
675
|
+
>
|
|
676
|
+
{processingStats.toCreate + processingStats.toUpdate > 0 ? (
|
|
677
|
+
<div className="space-y-1">
|
|
678
|
+
<p>
|
|
679
|
+
{processingStats.toCreate + processingStats.toUpdate} file{processingStats.toCreate + processingStats.toUpdate > 1 ? "s are" : " is"} ready
|
|
680
|
+
to process
|
|
681
|
+
</p>
|
|
682
|
+
<p>
|
|
683
|
+
{processingStats.toSkip > 0 &&
|
|
684
|
+
`${processingStats.toSkip} file${processingStats.toSkip > 1 ? "s are" : " is"} already in the system and will be skipped.`}
|
|
685
|
+
</p>
|
|
686
|
+
</div>
|
|
687
|
+
) : processingStats.toSkip > 0 ? (
|
|
673
688
|
<span>
|
|
674
|
-
|
|
675
|
-
the
|
|
689
|
+
All {processingStats.toSkip} file(s) already exist in the system and
|
|
690
|
+
will be skipped. You can proceed to view the results.
|
|
676
691
|
</span>
|
|
677
|
-
|
|
678
|
-
|
|
692
|
+
) : (
|
|
693
|
+
<span>No files to process.</span>
|
|
694
|
+
)}
|
|
695
|
+
</MessageBox>
|
|
679
696
|
|
|
680
|
-
{selectedType ? (
|
|
681
|
-
<div className="p-4 bg-gray-50 rounded-md border border-gray-100 mb-4">
|
|
682
|
-
<div className="font-medium mb-2">Files to process with selected type:</div>
|
|
683
|
-
<div className="text-sm">
|
|
684
|
-
{processingStats.toCreate + processingStats.toUpdate > 0 ? (
|
|
685
|
-
<div className="space-y-1">
|
|
686
|
-
<p>
|
|
687
|
-
{processingStats.toCreate + processingStats.toUpdate} file(s) ready
|
|
688
|
-
to process
|
|
689
|
-
{processingStats.toSkip > 0 &&
|
|
690
|
-
` (${processingStats.toSkip} will be skipped as they already exist)`}
|
|
691
|
-
</p>
|
|
692
|
-
<p className="text-green-600">
|
|
693
|
-
Files will be uploaded with type:{" "}
|
|
694
|
-
<strong>{selectedType.name}</strong>
|
|
695
|
-
</p>
|
|
696
|
-
{selectedType.description && (
|
|
697
|
-
<p className="text-gray-500 mt-1">{selectedType.description}</p>
|
|
698
|
-
)}
|
|
699
|
-
</div>
|
|
700
|
-
) : processingStats.toSkip > 0 ? (
|
|
701
|
-
<span>
|
|
702
|
-
All {processingStats.toSkip} file(s) already exist in the system and
|
|
703
|
-
will be skipped. You can proceed to view the results.
|
|
704
|
-
</span>
|
|
705
|
-
) : (
|
|
706
|
-
<span>No files to process.</span>
|
|
707
|
-
)}
|
|
708
|
-
</div>
|
|
709
|
-
</div>
|
|
710
|
-
) : (
|
|
711
|
-
<div className="p-4 bg-blue-50 rounded-md border border-blue-100 mb-4">
|
|
712
|
-
<div className="font-medium mb-2 flex items-center text-blue-700">
|
|
713
|
-
<CheckCircleIcon className="h-5 w-5 mr-1" />
|
|
714
|
-
Automatic Type Detection
|
|
715
|
-
</div>
|
|
716
|
-
<div className="text-sm text-blue-700">
|
|
717
|
-
{processingStats.toCreate + processingStats.toUpdate > 0 ? (
|
|
718
|
-
<div className="space-y-1">
|
|
719
|
-
<p>
|
|
720
|
-
{processingStats.toCreate + processingStats.toUpdate} file(s) ready
|
|
721
|
-
to process
|
|
722
|
-
{processingStats.toSkip > 0 &&
|
|
723
|
-
` (${processingStats.toSkip} will be skipped as they already exist)`}
|
|
724
|
-
</p>
|
|
725
|
-
<p className="mt-2">
|
|
726
|
-
<strong>
|
|
727
|
-
Vertesia will analyze each file and select the most appropriate
|
|
728
|
-
type.
|
|
729
|
-
</strong>
|
|
730
|
-
</p>
|
|
731
|
-
<p className="mt-1">
|
|
732
|
-
This is recommended for most uploads and ensures optimal processing.
|
|
733
|
-
</p>
|
|
734
|
-
</div>
|
|
735
|
-
) : processingStats.toSkip > 0 ? (
|
|
736
|
-
<span>
|
|
737
|
-
All {processingStats.toSkip} file(s) already exist in the system and
|
|
738
|
-
will be skipped. You can proceed to view the results.
|
|
739
|
-
</span>
|
|
740
|
-
) : (
|
|
741
|
-
<span>No files to process.</span>
|
|
742
|
-
)}
|
|
743
|
-
</div>
|
|
744
|
-
</div>
|
|
745
|
-
)}
|
|
746
697
|
</>
|
|
747
698
|
)}
|
|
748
|
-
</
|
|
699
|
+
</VModalBody>
|
|
749
700
|
);
|
|
750
701
|
}
|
|
751
702
|
|
|
752
|
-
// Step 3: Upload in progress
|
|
703
|
+
// Step 3: Upload in progress #todo: update styles
|
|
753
704
|
if (isUploading) {
|
|
754
705
|
return (
|
|
755
|
-
<
|
|
706
|
+
<VModalBody>
|
|
756
707
|
{/* Collection and folder information if available */}
|
|
757
708
|
{renderLocationInfo()}
|
|
758
709
|
|
|
759
710
|
<div className="mb-4">
|
|
760
|
-
<div className="flex justify-between items-center mb-2">
|
|
761
|
-
<div className="text-lg font-medium">Uploading Files</div>
|
|
762
|
-
<div className="text-sm text-muted">
|
|
763
|
-
{Math.round(overallProgress)}% complete
|
|
764
|
-
</div>
|
|
765
|
-
</div>
|
|
766
|
-
|
|
767
711
|
{/* Progress bar */}
|
|
768
|
-
<div className="h-2 bg-
|
|
712
|
+
<div className="h-2 bg-muted/20 rounded-full overflow-hidden">
|
|
769
713
|
<div
|
|
770
|
-
className="h-full bg-
|
|
714
|
+
className="h-full bg-primary rounded-full"
|
|
771
715
|
style={{ width: `${overallProgress}%` }}
|
|
772
716
|
/>
|
|
773
717
|
</div>
|
|
@@ -778,17 +722,17 @@ export function DocumentUploadModal({
|
|
|
778
722
|
{fileStatuses.map((fileStatus, index) => (
|
|
779
723
|
<div
|
|
780
724
|
key={`${fileStatus.file.name}-${index}`}
|
|
781
|
-
className="flex items-center py-2 border-b border-
|
|
725
|
+
className="flex items-center py-2 border-b border-border last:border-b-0"
|
|
782
726
|
>
|
|
783
727
|
<div className="mr-3">
|
|
784
728
|
{fileStatus.status === "pending" && (
|
|
785
|
-
<FileIcon className="
|
|
729
|
+
<FileIcon className="size-5 text-muted" />
|
|
786
730
|
)}
|
|
787
731
|
{fileStatus.status === "uploading" && <Spinner size="sm" />}
|
|
788
732
|
{fileStatus.status === "success" && (
|
|
789
|
-
<CheckCircleIcon className="
|
|
733
|
+
<CheckCircleIcon className="size-5 text-success" />
|
|
790
734
|
)}
|
|
791
|
-
{fileStatus.status === "error" && <XCircleIcon className="
|
|
735
|
+
{fileStatus.status === "error" && <XCircleIcon className="size-5 text-destructive" />}
|
|
792
736
|
</div>
|
|
793
737
|
<div className="flex-1 min-w-0">
|
|
794
738
|
<div className="truncate font-medium">{fileStatus.file.name}</div>
|
|
@@ -807,16 +751,14 @@ export function DocumentUploadModal({
|
|
|
807
751
|
</div>
|
|
808
752
|
))}
|
|
809
753
|
</div>
|
|
810
|
-
</
|
|
754
|
+
</VModalBody>
|
|
811
755
|
);
|
|
812
756
|
}
|
|
813
757
|
|
|
814
758
|
// Step 4: Upload complete, show results
|
|
815
759
|
return (
|
|
816
|
-
<
|
|
760
|
+
<VModalBody>
|
|
817
761
|
<div className="mb-4">
|
|
818
|
-
<div className="text-lg font-medium mb-2">Upload Complete</div>
|
|
819
|
-
|
|
820
762
|
{/* Collection and folder information if available */}
|
|
821
763
|
{renderLocationInfo()}
|
|
822
764
|
|
|
@@ -847,7 +789,7 @@ export function DocumentUploadModal({
|
|
|
847
789
|
collection={collectionData?.name}
|
|
848
790
|
/>
|
|
849
791
|
</div>
|
|
850
|
-
</
|
|
792
|
+
</VModalBody>
|
|
851
793
|
);
|
|
852
794
|
};
|
|
853
795
|
|
|
@@ -855,7 +797,7 @@ export function DocumentUploadModal({
|
|
|
855
797
|
// Type-selection-only mode
|
|
856
798
|
if (showTypeSelectionOnly) {
|
|
857
799
|
return (
|
|
858
|
-
<
|
|
800
|
+
<VModalFooter>
|
|
859
801
|
<Button variant="ghost" onClick={handleClose}>
|
|
860
802
|
Cancel
|
|
861
803
|
</Button>
|
|
@@ -884,18 +826,18 @@ export function DocumentUploadModal({
|
|
|
884
826
|
>
|
|
885
827
|
{selectedType ? `Use ${selectedType.name}` : "Use Automatic Type Detection"}
|
|
886
828
|
</Button>
|
|
887
|
-
</
|
|
829
|
+
</VModalFooter>
|
|
888
830
|
);
|
|
889
831
|
}
|
|
890
832
|
|
|
891
833
|
// File selection step - only show cancel
|
|
892
834
|
if (files.length === 0 && !hideFileSelection) {
|
|
893
835
|
return (
|
|
894
|
-
<
|
|
836
|
+
<VModalFooter>
|
|
895
837
|
<Button variant="ghost" onClick={handleClose}>
|
|
896
838
|
Cancel
|
|
897
839
|
</Button>
|
|
898
|
-
</
|
|
840
|
+
</VModalFooter>
|
|
899
841
|
);
|
|
900
842
|
}
|
|
901
843
|
|
|
@@ -905,39 +847,36 @@ export function DocumentUploadModal({
|
|
|
905
847
|
const canUpload = processingDone;
|
|
906
848
|
|
|
907
849
|
return (
|
|
908
|
-
<
|
|
850
|
+
<VModalFooter>
|
|
909
851
|
<Button variant="ghost" onClick={handleClose}>
|
|
910
852
|
Cancel
|
|
911
853
|
</Button>
|
|
912
854
|
<Button
|
|
913
855
|
disabled={!canUpload}
|
|
914
856
|
onClick={handleUpload}
|
|
915
|
-
className={!selectedType ? "bg-blue-600 hover:bg-blue-700" : ""}
|
|
916
857
|
>
|
|
917
858
|
{processingStats.toCreate + processingStats.toUpdate > 0
|
|
918
|
-
?
|
|
919
|
-
? `Upload with ${selectedType.name}`
|
|
920
|
-
: "Upload with Automatic Type Detection"
|
|
859
|
+
? "Upload"
|
|
921
860
|
: "Continue"}
|
|
922
861
|
</Button>
|
|
923
|
-
</
|
|
862
|
+
</VModalFooter>
|
|
924
863
|
);
|
|
925
864
|
}
|
|
926
865
|
|
|
927
866
|
// Upload in progress - can't cancel
|
|
928
867
|
if (isUploading) {
|
|
929
868
|
return (
|
|
930
|
-
<
|
|
869
|
+
<VModalFooter>
|
|
931
870
|
<Button variant="ghost" disabled>
|
|
932
871
|
Uploading...
|
|
933
872
|
</Button>
|
|
934
|
-
</
|
|
873
|
+
</VModalFooter>
|
|
935
874
|
);
|
|
936
875
|
}
|
|
937
876
|
|
|
938
877
|
// Upload complete - close or upload more
|
|
939
878
|
return (
|
|
940
|
-
<
|
|
879
|
+
<VModalFooter>
|
|
941
880
|
<Button
|
|
942
881
|
variant="ghost"
|
|
943
882
|
onClick={() => {
|
|
@@ -955,16 +894,23 @@ export function DocumentUploadModal({
|
|
|
955
894
|
>
|
|
956
895
|
Upload More
|
|
957
896
|
</Button>
|
|
958
|
-
<Button onClick={
|
|
959
|
-
|
|
897
|
+
<Button onClick={() => {
|
|
898
|
+
if (onUploadComplete && result) {
|
|
899
|
+
onUploadComplete(result);
|
|
900
|
+
}
|
|
901
|
+
handleClose();
|
|
902
|
+
}}>
|
|
903
|
+
Close
|
|
904
|
+
</Button>
|
|
905
|
+
</VModalFooter>
|
|
960
906
|
);
|
|
961
907
|
};
|
|
962
908
|
|
|
963
909
|
return (
|
|
964
|
-
<
|
|
965
|
-
<
|
|
910
|
+
<VModal key={modalKey} isOpen={isOpen} onClose={handleClose} className="mx-auto">
|
|
911
|
+
<VModalTitle description={_description}>{_title}</VModalTitle>
|
|
966
912
|
{renderModalContent()}
|
|
967
913
|
{renderModalFooter()}
|
|
968
|
-
</
|
|
914
|
+
</VModal>
|
|
969
915
|
);
|
|
970
916
|
}
|
|
@@ -6,6 +6,7 @@ import { json } from '@codemirror/lang-json';
|
|
|
6
6
|
import { CodeMirrorEditor, EditorApi, SchemaEditor, useSchema } from '@vertesia/ui/widgets';
|
|
7
7
|
import { Button, useToast } from '@vertesia/ui/core';
|
|
8
8
|
import { ContentObjectType } from '@vertesia/common';
|
|
9
|
+
import { Ajv } from "ajv";
|
|
9
10
|
|
|
10
11
|
const CODE_MIRROR_EXTENSIONS = [basicSetup, json()];
|
|
11
12
|
|
|
@@ -69,6 +70,7 @@ export function ObjectSchemaEditor({ objectType, onSchemaUpdate }: ObjectSchemaE
|
|
|
69
70
|
const value = editorRef.current.getValue();
|
|
70
71
|
try {
|
|
71
72
|
const newSchema = contentToJson(value);
|
|
73
|
+
validateSchema(newSchema);
|
|
72
74
|
schema.replaceSchema(newSchema);
|
|
73
75
|
} catch (err: any) {
|
|
74
76
|
toast({
|
|
@@ -124,3 +126,16 @@ function contentToJson(content: string | undefined | null) {
|
|
|
124
126
|
|
|
125
127
|
return JSON.parse(content.trim());
|
|
126
128
|
}
|
|
129
|
+
|
|
130
|
+
const validateSchema = (schema: Record<string, any>) => {
|
|
131
|
+
try {
|
|
132
|
+
const ajv = new Ajv({
|
|
133
|
+
strict: true, // Enable strict mode to ensure all properties are validated
|
|
134
|
+
});
|
|
135
|
+
// Compile the schema. This implicitly validates the schema definition
|
|
136
|
+
// against the JSON Schema draft that ajv supports by default.
|
|
137
|
+
ajv.compile(schema);
|
|
138
|
+
} catch (error: any) {
|
|
139
|
+
throw new Error(`Invalid JSON Schema definition: ${error.message}`);
|
|
140
|
+
}
|
|
141
|
+
};
|