@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
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { SignupData, SignupPayload } from "@vertesia/common";
|
|
2
|
+
import { Button, useSafeLayoutEffect } from "@vertesia/ui/core";
|
|
3
|
+
import { Env } from "@vertesia/ui/env";
|
|
4
|
+
import { UserNotFoundError, useUserSession, useUXTracking } from "@vertesia/ui/session";
|
|
5
|
+
import clsx from "clsx";
|
|
6
|
+
import { useEffect, useState } from "react";
|
|
7
|
+
import EnterpriseSigninButton from "./EnterpriseSigninButton";
|
|
8
|
+
import GitHubSignInButton from "./GitHubSignInButton";
|
|
9
|
+
import GoogleSignInButton from "./GoogleSignInButton";
|
|
10
|
+
import MicrosoftSignInButton from "./MicrosoftSigninButton";
|
|
11
|
+
import SignupForm from "./SignupForm";
|
|
12
|
+
|
|
13
|
+
interface SigninScreenProps {
|
|
14
|
+
isNested?: boolean;
|
|
15
|
+
allowedPrefix?: string;
|
|
16
|
+
lightLogo?: string;
|
|
17
|
+
darkLogo?: string;
|
|
18
|
+
}
|
|
19
|
+
export function SigninScreen({ allowedPrefix, isNested = false, lightLogo, darkLogo }: SigninScreenProps) {
|
|
20
|
+
const [allow, setAllow] = useState(false);
|
|
21
|
+
useSafeLayoutEffect(() => {
|
|
22
|
+
allowedPrefix && setAllow(window.location.href.startsWith(allowedPrefix));
|
|
23
|
+
}, []);
|
|
24
|
+
return allow ? null : <SigninScreenImpl isNested={isNested} lightLogo={lightLogo} darkLogo={darkLogo} />;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function SigninScreenImpl({ isNested = false, lightLogo, darkLogo }: SigninScreenProps) {
|
|
28
|
+
const { isLoading, user, authError } = useUserSession();
|
|
29
|
+
|
|
30
|
+
return !isLoading && !user ? (
|
|
31
|
+
<div
|
|
32
|
+
style={{ zIndex: 999998 }}
|
|
33
|
+
className={(isNested ? "absolute" : "fixed") + "overflow-y-auto "}
|
|
34
|
+
>
|
|
35
|
+
<div
|
|
36
|
+
className={clsx(
|
|
37
|
+
"flex flex-col items-center justify-center py-14 px-4",
|
|
38
|
+
)}
|
|
39
|
+
>
|
|
40
|
+
|
|
41
|
+
<StandardSigninPanel authError={authError} lightLogo={lightLogo} darkLogo={darkLogo} />
|
|
42
|
+
<div className="flex gap-x-6 mt-10 justify-center text-muted">
|
|
43
|
+
<a href="https://vertesiahq.com/privacy" className="text-sm">
|
|
44
|
+
Privacy Policy
|
|
45
|
+
</a>
|
|
46
|
+
<a href="https://vertesiahq.com/terms" className="text-sm">
|
|
47
|
+
Terms of Service
|
|
48
|
+
</a>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
) : null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function StandardSigninPanel({ authError, darkLogo, lightLogo }: {
|
|
56
|
+
authError?: Error,
|
|
57
|
+
darkLogo?: string,
|
|
58
|
+
lightLogo?: string
|
|
59
|
+
}) {
|
|
60
|
+
const [signupData, setSignupData] = useState<SignupData | undefined>(undefined);
|
|
61
|
+
const [collectSignupData, setCollectSignupData] = useState(false);
|
|
62
|
+
const { signOut } = useUserSession();
|
|
63
|
+
const { trackEvent } = useUXTracking();
|
|
64
|
+
|
|
65
|
+
history.replaceState({}, '', '/');
|
|
66
|
+
|
|
67
|
+
const goBack = () => {
|
|
68
|
+
console.log("Going back, signing out");
|
|
69
|
+
setSignupData(undefined);
|
|
70
|
+
setCollectSignupData(false);
|
|
71
|
+
signOut();
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const goToSignup = () => {
|
|
75
|
+
setSignupData(undefined);
|
|
76
|
+
setCollectSignupData(true);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (authError instanceof UserNotFoundError) {
|
|
81
|
+
console.log("User not found, redirecting to signup");
|
|
82
|
+
goToSignup();
|
|
83
|
+
}
|
|
84
|
+
}, [authError]);
|
|
85
|
+
|
|
86
|
+
const onSignup = (data: SignupData, fbToken: string) => {
|
|
87
|
+
console.log("Got Signup data", data);
|
|
88
|
+
setSignupData(data);
|
|
89
|
+
const payload: SignupPayload = {
|
|
90
|
+
signupData: data,
|
|
91
|
+
firebaseToken: fbToken,
|
|
92
|
+
};
|
|
93
|
+
fetch(Env.endpoints.studio + "/auth/signup", {
|
|
94
|
+
method: "POST",
|
|
95
|
+
headers: { "Content-Type": "application/json" },
|
|
96
|
+
body: JSON.stringify(payload),
|
|
97
|
+
}).then((res) => {
|
|
98
|
+
console.log("Signup successful", payload, res);
|
|
99
|
+
|
|
100
|
+
trackEvent("sign_up");
|
|
101
|
+
window.location.href = "/";
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<>
|
|
107
|
+
{lightLogo && <img src={lightLogo} alt='logo' className='h-15 block dark:hidden' />}
|
|
108
|
+
{darkLogo && <img src={darkLogo} alt='logo' className='h-15 hidden dark:block' />}
|
|
109
|
+
|
|
110
|
+
{signupData && (
|
|
111
|
+
<div className="my-6">
|
|
112
|
+
Need to make a change?{" "}
|
|
113
|
+
<Button onClick={goToSignup}> Go back</Button>
|
|
114
|
+
</div>
|
|
115
|
+
)}
|
|
116
|
+
<div className="flex flex-col space-y-2">
|
|
117
|
+
{collectSignupData && !localStorage.getItem('tenantName') ? (
|
|
118
|
+
<SignupForm onSignup={onSignup} goBack={goBack} />
|
|
119
|
+
) : (
|
|
120
|
+
|
|
121
|
+
<div className="flex flex-col">
|
|
122
|
+
<div className="my-4">
|
|
123
|
+
<h2 className="text-2xl font-bold text-center">Log in or Sign up</h2>
|
|
124
|
+
</div>
|
|
125
|
+
<div className="max-w-2xl text-center my-2 px-2">
|
|
126
|
+
First time here? No problem, it's free to try!
|
|
127
|
+
<br />
|
|
128
|
+
We'll just ask you a couple of questions next and you'll be on your way.
|
|
129
|
+
</div>
|
|
130
|
+
<div className="flex items-center flex-col">
|
|
131
|
+
<div className="py-4 w-70">
|
|
132
|
+
<GoogleSignInButton />
|
|
133
|
+
<GitHubSignInButton />
|
|
134
|
+
<MicrosoftSignInButton />
|
|
135
|
+
</div>
|
|
136
|
+
<div className="flex items-center flex-row w-70 text-muted">
|
|
137
|
+
<hr className="w-full" />
|
|
138
|
+
<div className="px-2 text-xs">OR</div>
|
|
139
|
+
<hr className="w-full" />
|
|
140
|
+
</div>
|
|
141
|
+
<div className="py-4 w-70">
|
|
142
|
+
<EnterpriseSigninButton />
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
{authError && (
|
|
146
|
+
<div className="text-center">
|
|
147
|
+
<div className="">
|
|
148
|
+
Sorry, we have not been able to sign you in.
|
|
149
|
+
<br />
|
|
150
|
+
Please try again or contact
|
|
151
|
+
<a className='text-info mx-1' href="mailto:support@vertesiahq.com">support@vertesiahq.com</a>
|
|
152
|
+
if it persists.
|
|
153
|
+
<pre className="mt-2">Error: {authError.message}</pre>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
)}
|
|
157
|
+
</div>
|
|
158
|
+
)}
|
|
159
|
+
</div>
|
|
160
|
+
</>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { SignupData } from "@vertesia/common";
|
|
2
|
+
import { Button, Input, VSelectBox, SelectStack } from "@vertesia/ui/core";
|
|
3
|
+
import { User, getAuth } from "firebase/auth";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
interface CompanySizeOption {
|
|
8
|
+
id: number;
|
|
9
|
+
label: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const companySizeOptions: CompanySizeOption[] = [
|
|
13
|
+
{ id: 1, label: "1-10 employees" },
|
|
14
|
+
{ id: 11, label: "11-100 employees" },
|
|
15
|
+
{ id: 101, label: "101-1000 employees" },
|
|
16
|
+
{ id: 1001, label: "1001-5000 employees" },
|
|
17
|
+
{ id: 5001, label: "5000+ employees" },
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const accountTypeOptions = [
|
|
21
|
+
{
|
|
22
|
+
id: "personal",
|
|
23
|
+
label: "Personal",
|
|
24
|
+
description: "For personal use, or for a small team.",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "company",
|
|
28
|
+
label: "Company",
|
|
29
|
+
description: "For a company or organization.",
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
const projectMaturityOptions = [
|
|
34
|
+
{ id: "testing", label: "Just Testing or Evaluating LLMs" },
|
|
35
|
+
{ id: "exploring", label: "Actively Exploring LLMs on a Project" },
|
|
36
|
+
{ id: "using", label: "Already Using LLMs in Production" },
|
|
37
|
+
{ id: "migrating", label: "Migrating to different LLMs" },
|
|
38
|
+
{ id: "other", label: "Other" },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
interface SignupFormProps {
|
|
42
|
+
onSignup: (data: SignupData, fbToken: string) => void;
|
|
43
|
+
goBack: () => void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default function SignupForm({ onSignup, goBack }: SignupFormProps) {
|
|
47
|
+
const [accountType, setAccountType] = useState<string | undefined>(undefined);
|
|
48
|
+
const [companySize, setCompanySize] = useState<CompanySizeOption | undefined>(undefined);
|
|
49
|
+
const [companyName, setCompanyName] = useState<string | undefined>(undefined);
|
|
50
|
+
const [companyWebsite, setCompanyWebsite] = useState<string | undefined>(undefined);
|
|
51
|
+
const [projectMaturity, setProjectMaturity] = useState<string | undefined>(undefined);
|
|
52
|
+
const [fbUser, setFbUser] = useState<User | undefined>(undefined);
|
|
53
|
+
|
|
54
|
+
const [error, setError] = useState<string | undefined>(undefined);
|
|
55
|
+
const isCompany = accountType === "company";
|
|
56
|
+
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
const user = getAuth().currentUser;
|
|
59
|
+
if (!user) {
|
|
60
|
+
console.error('No user found');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
setFbUser(user);
|
|
64
|
+
}, [fbUser]);
|
|
65
|
+
|
|
66
|
+
const isValid = () => {
|
|
67
|
+
if (!accountType) {
|
|
68
|
+
setError("Please select an account type");
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
if (isCompany && !companyName) {
|
|
72
|
+
setError("Please enter an organization name");
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (isCompany && !companySize) {
|
|
77
|
+
setError("Please select a company size");
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return true
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
const onSubmit = async () => {
|
|
86
|
+
if (!isValid()) return;
|
|
87
|
+
if (!accountType) return;
|
|
88
|
+
|
|
89
|
+
const signupData = {
|
|
90
|
+
accountType: accountType,
|
|
91
|
+
companyName: companyName,
|
|
92
|
+
companySize: companySize?.id,
|
|
93
|
+
companyWebsite: companyWebsite,
|
|
94
|
+
maturity: projectMaturity,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
window.localStorage.setItem("composableSignupData", JSON.stringify(signupData));
|
|
98
|
+
|
|
99
|
+
const fbToken = await getAuth().currentUser?.getIdToken();
|
|
100
|
+
console.log('Got firebase token', getAuth(), fbToken);
|
|
101
|
+
if (!fbToken) {
|
|
102
|
+
console.error('No firebase token found');
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
onSignup(signupData, fbToken);
|
|
107
|
+
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<div className="flex flex-col space-y-2">
|
|
112
|
+
<div className="prose">
|
|
113
|
+
<p className="prose text-sm text-muted pt-4">
|
|
114
|
+
Welcome to Vertesia, {fbUser?.displayName} ({fbUser?.email}).
|
|
115
|
+
Please tell us a little bit about yourself and you'll be on your way.
|
|
116
|
+
No credit card is required.
|
|
117
|
+
</p>
|
|
118
|
+
{error &&
|
|
119
|
+
<div className="text-destructive">{error}</div>
|
|
120
|
+
}
|
|
121
|
+
</div>
|
|
122
|
+
<FormItem label="Account Type">
|
|
123
|
+
<SelectStack
|
|
124
|
+
options={accountTypeOptions}
|
|
125
|
+
selected={accountTypeOptions.find((option) => option.id === accountType)}
|
|
126
|
+
onSelect={(option) => setAccountType(option.id)}
|
|
127
|
+
/>
|
|
128
|
+
</FormItem>
|
|
129
|
+
{isCompany &&
|
|
130
|
+
<>
|
|
131
|
+
<FormItem label="Company Size">
|
|
132
|
+
<VSelectBox className="w-full border border-accent bg-muted"
|
|
133
|
+
value={companySize}
|
|
134
|
+
options={companySizeOptions}
|
|
135
|
+
onChange={setCompanySize}
|
|
136
|
+
optionLabel={(option) => option?.label}
|
|
137
|
+
placeholder='Select Company Size'
|
|
138
|
+
/>
|
|
139
|
+
</FormItem>
|
|
140
|
+
<FormItem label="Company Name">
|
|
141
|
+
<Input value={companyName} onChange={setCompanyName} type="text" required={true} />
|
|
142
|
+
</FormItem>
|
|
143
|
+
<FormItem label="Company Website">
|
|
144
|
+
<Input value={companyWebsite} onChange={setCompanyWebsite} type="text" />
|
|
145
|
+
</FormItem>
|
|
146
|
+
</>
|
|
147
|
+
}
|
|
148
|
+
<FormItem label="Project Maturity">
|
|
149
|
+
<VSelectBox className="w-full border border-accent bg-muted"
|
|
150
|
+
options={projectMaturityOptions}
|
|
151
|
+
value={projectMaturityOptions.find((option) => option.id === projectMaturity)}
|
|
152
|
+
optionLabel={(option) => option?.label}
|
|
153
|
+
placeholder='Select Project Maturity'
|
|
154
|
+
onChange={(option) => setProjectMaturity(option?.id)}
|
|
155
|
+
/>
|
|
156
|
+
</FormItem>
|
|
157
|
+
<div className="pt-8 flex flex-col">
|
|
158
|
+
<Button variant="primary" onClick={onSubmit} size="xl">
|
|
159
|
+
<span className="text-lg">Sign Up</span>
|
|
160
|
+
</Button>
|
|
161
|
+
<Button variant="ghost" size="xl" className="mt-4" onClick={goBack}>
|
|
162
|
+
<span className="">Wrong account, go back</span>
|
|
163
|
+
</Button>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function FormItem({ label, children }: { label: string, children: React.ReactNode }) {
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
<div className="flex flex-col space-y-2 pt-4">
|
|
173
|
+
<div className="text-sm text-muted">{label}</div>
|
|
174
|
+
{children}
|
|
175
|
+
</div>
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
|
|
3
|
+
import { AccountRef, ProjectRef } from '@vertesia/common'
|
|
4
|
+
import { Button, Center, ErrorBox, Input, SelectBox, Spinner, useFetch, useToast } from '@vertesia/ui/core'
|
|
5
|
+
import { Env } from "@vertesia/ui/env"
|
|
6
|
+
import { useLocation } from "@vertesia/ui/router"
|
|
7
|
+
import { fetchComposableTokenFromFirebaseToken, useUserSession } from '@vertesia/ui/session'
|
|
8
|
+
|
|
9
|
+
interface ProfileData {
|
|
10
|
+
profile?: string
|
|
11
|
+
account?: string
|
|
12
|
+
project?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface LoginResult extends Required<ProfileData> {
|
|
16
|
+
token: string
|
|
17
|
+
studio_server_url: string
|
|
18
|
+
zeno_server_url: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface ClientInfo extends ProfileData {
|
|
22
|
+
redirect: string
|
|
23
|
+
code: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getClientInfo(location: Location): ClientInfo | null {
|
|
27
|
+
const params = new URLSearchParams(location.search)
|
|
28
|
+
let redirect = params.get('redirect_uri')
|
|
29
|
+
const code = params.get('code')
|
|
30
|
+
if (!redirect || !code) {
|
|
31
|
+
return null
|
|
32
|
+
}
|
|
33
|
+
redirect = decodeURI(redirect)
|
|
34
|
+
if (!redirect.startsWith('http://127.0.0.1:') && !redirect.startsWith('http://localhost:')) {
|
|
35
|
+
return null
|
|
36
|
+
}
|
|
37
|
+
const profile = params.get('profile') ?? "default"
|
|
38
|
+
const project = params.get('project') ?? undefined
|
|
39
|
+
const account = params.get('account') ?? undefined
|
|
40
|
+
return { redirect, code, profile, project, account }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function TerminalLogin() {
|
|
44
|
+
const [payload, setPayload] = useState<LoginResult | undefined>()
|
|
45
|
+
const [error, setError] = useState<Error>()
|
|
46
|
+
const location = useLocation()
|
|
47
|
+
const clientInfo = getClientInfo(location)
|
|
48
|
+
const toast = useToast()
|
|
49
|
+
|
|
50
|
+
const onAccept = async (data: ProfileData) => {
|
|
51
|
+
if (!clientInfo) return
|
|
52
|
+
if (!data.profile) {
|
|
53
|
+
toast({
|
|
54
|
+
title: 'Profile is required',
|
|
55
|
+
description: 'Please enter a profile name to save the client authorization',
|
|
56
|
+
status: 'error',
|
|
57
|
+
duration: 2000
|
|
58
|
+
})
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
if (!data.account) {
|
|
62
|
+
toast({
|
|
63
|
+
title: 'Account is required',
|
|
64
|
+
description: 'Please select an account to authorize the client to access the ComposablePrompts servers',
|
|
65
|
+
status: 'error',
|
|
66
|
+
duration: 2000
|
|
67
|
+
})
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
if (!data.project) {
|
|
71
|
+
toast({
|
|
72
|
+
title: 'Project is required',
|
|
73
|
+
description: 'Please select a project to authorize the client to access the ComposablePrompts servers',
|
|
74
|
+
status: 'error',
|
|
75
|
+
duration: 2000
|
|
76
|
+
})
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// expire in 1 day
|
|
81
|
+
let payload: LoginResult | undefined
|
|
82
|
+
try {
|
|
83
|
+
const token = await fetchComposableTokenFromFirebaseToken(data.account, data.project, 24 * 3600)
|
|
84
|
+
if (token) {
|
|
85
|
+
payload = {
|
|
86
|
+
...data,
|
|
87
|
+
studio_server_url: Env.endpoints.studio,
|
|
88
|
+
zeno_server_url: Env.endpoints.zeno,
|
|
89
|
+
token,
|
|
90
|
+
} as LoginResult
|
|
91
|
+
await fetch(clientInfo.redirect, {
|
|
92
|
+
method: 'POST',
|
|
93
|
+
headers: {
|
|
94
|
+
'Content-Type': 'application/json'
|
|
95
|
+
},
|
|
96
|
+
body: JSON.stringify(payload)
|
|
97
|
+
})
|
|
98
|
+
setPayload(payload)
|
|
99
|
+
} else {
|
|
100
|
+
toast({
|
|
101
|
+
title: 'Failed to get composable token',
|
|
102
|
+
status: 'error',
|
|
103
|
+
duration: 5000
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
} catch (err: any) {
|
|
107
|
+
if (payload) {
|
|
108
|
+
setError(err)
|
|
109
|
+
setPayload(payload)
|
|
110
|
+
} else {
|
|
111
|
+
toast({
|
|
112
|
+
title: 'Error authorizing client',
|
|
113
|
+
description: err.message,
|
|
114
|
+
status: 'error',
|
|
115
|
+
duration: 5000
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const getPageContent = () => {
|
|
122
|
+
if (!clientInfo) {
|
|
123
|
+
return <ErrorBox title='Invalid request'>This page should be called by a terminal client to authenticate against the ComposablePrompts servers</ErrorBox>
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return payload
|
|
127
|
+
? <AuthDoneScreen payload={payload} error={error} />
|
|
128
|
+
: <AuthAcceptScreen clientInfo={clientInfo} onAccept={onAccept} />
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const page = getPageContent()
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<div className="w-full flex flex-col items-center gap-4 mt-24">{page}</div>
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
interface AuthAcceptScreenProps {
|
|
139
|
+
onAccept: (data: ProfileData) => void
|
|
140
|
+
clientInfo: ClientInfo
|
|
141
|
+
}
|
|
142
|
+
function AuthAcceptScreen({ onAccept, clientInfo }: Readonly<AuthAcceptScreenProps>) {
|
|
143
|
+
const { client, user } = useUserSession()
|
|
144
|
+
const { data: allProjects, error } = useFetch(() => user ? client.projects.list() : Promise.resolve([]), [user])
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
if (error) {
|
|
148
|
+
return <ErrorBox title='Error loading projects'>{error.message}</ErrorBox>
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const getEnvironmentName = () => {
|
|
152
|
+
if (Env.isLocalDev) {
|
|
153
|
+
return "Local Dev"
|
|
154
|
+
} else if (Env.isDev) {
|
|
155
|
+
return "Staging"
|
|
156
|
+
}
|
|
157
|
+
return "Production"
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const envName = getEnvironmentName()
|
|
161
|
+
|
|
162
|
+
return user && allProjects ? (
|
|
163
|
+
<>
|
|
164
|
+
<div className='w-1/3'>
|
|
165
|
+
<div className="mb-4 text-xl font-semibold text-gray-800">
|
|
166
|
+
Authorizing client on {envName} environment.
|
|
167
|
+
</div>
|
|
168
|
+
<div className='mb-2 text-md text-gray-800'>
|
|
169
|
+
<div>A client app wants authorization to access the composable prompt servers in your name.</div>
|
|
170
|
+
<div>The client app code is <b>{clientInfo.code}</b>. You can check if the code is correct in the terminal.</div>
|
|
171
|
+
</div>
|
|
172
|
+
<div className='mb-2 text-sm text-gray-600'>
|
|
173
|
+
<div>You must choose the target account and project for the client to access.</div>
|
|
174
|
+
<div>Also, enter a profile name that will be used to save the authorization in your client configuration.</div>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
<ProfileForm onAccept={onAccept} allProjects={allProjects} data={clientInfo} />
|
|
178
|
+
</>
|
|
179
|
+
) : <Spinner size='lg' />
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function AuthDoneScreen({ payload, error }: Readonly<{ payload: LoginResult, error?: Error }>) {
|
|
183
|
+
const toast = useToast()
|
|
184
|
+
const onCopy = () => {
|
|
185
|
+
if (payload) {
|
|
186
|
+
navigator.clipboard.writeText(JSON.stringify(payload))
|
|
187
|
+
toast({
|
|
188
|
+
title: 'Authentication Payload copied',
|
|
189
|
+
description: error ? 'You can paste the authentication payload in the terminal to authenticate the client.' : 'You can close the page now.',
|
|
190
|
+
status: 'success',
|
|
191
|
+
duration: 5000
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return (
|
|
197
|
+
<div>
|
|
198
|
+
{
|
|
199
|
+
error ?
|
|
200
|
+
<div>
|
|
201
|
+
<ErrorBox title='Failed to send the authorization token to the cli tool'>This can happen due to security checks on Safari. The error is "{error.message}"</ErrorBox>
|
|
202
|
+
<div>Don't worry, you can still authenticate the cli tool by pasting the authentication token in the terminal.
|
|
203
|
+
You can close this page.</div>
|
|
204
|
+
</div>
|
|
205
|
+
: <div>The client is authenticated. You can close this page.</div>
|
|
206
|
+
}
|
|
207
|
+
<Center className="mt-4">
|
|
208
|
+
<Button variant='secondary' onClick={onCopy}>Copy the Authentication Payload</Button>
|
|
209
|
+
</Center>
|
|
210
|
+
</div>
|
|
211
|
+
)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
interface ProfileFormProps {
|
|
215
|
+
onAccept: (data: ProfileData) => void
|
|
216
|
+
allProjects: ProjectRef[]
|
|
217
|
+
data: ProfileData
|
|
218
|
+
}
|
|
219
|
+
function ProfileForm({ allProjects, data, onAccept }: Readonly<ProfileFormProps>) {
|
|
220
|
+
const { accounts, account, project } = useUserSession()
|
|
221
|
+
const [currentData, setCurrentData] = useState<ProfileData>(() => ({
|
|
222
|
+
profile: data.profile,
|
|
223
|
+
account: data.account ?? account?.id,
|
|
224
|
+
project: data.project ?? project?.id,
|
|
225
|
+
}))
|
|
226
|
+
|
|
227
|
+
const onChangeProfile = (value: string) => {
|
|
228
|
+
setCurrentData({ ...currentData, profile: value })
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const onChangeAccount = (value: AccountRef) => {
|
|
232
|
+
setCurrentData({ ...currentData, account: value.id, project: undefined })
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const onChangeProject = (value: ProjectRef) => {
|
|
236
|
+
setCurrentData({ ...currentData, project: value.id })
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const projects = allProjects.filter(p => p.account === currentData.account)
|
|
240
|
+
|
|
241
|
+
return (
|
|
242
|
+
<div className='w-1/3'>
|
|
243
|
+
<div className="mb-4 flex flex-col gap-2">
|
|
244
|
+
<span className="font-semibold text-gray-600">Profile Name</span>
|
|
245
|
+
<Input type='text' value={currentData.profile} onChange={onChangeProfile} />
|
|
246
|
+
</div>
|
|
247
|
+
<div className="mb-4 flex flex-col gap-2">
|
|
248
|
+
<span className="font-semibold text-gray-600">Account</span>
|
|
249
|
+
<SelectAccount value={currentData.account} onChange={onChangeAccount} accounts={accounts || []} />
|
|
250
|
+
</div>
|
|
251
|
+
<div className="mb-4 flex flex-col gap-2">
|
|
252
|
+
<span className="font-semibold text-gray-600">Project</span>
|
|
253
|
+
<SelectProject value={currentData.project} onChange={onChangeProject} projects={projects} />
|
|
254
|
+
</div>
|
|
255
|
+
<div className="pt-2">
|
|
256
|
+
<Button size='xl' onClick={() => onAccept(currentData)}>Authorize Client</Button>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
interface SelectAccountProps {
|
|
263
|
+
value?: string
|
|
264
|
+
accounts: AccountRef[]
|
|
265
|
+
onChange: (value: AccountRef) => void
|
|
266
|
+
}
|
|
267
|
+
function SelectAccount({ value, accounts, onChange }: Readonly<SelectAccountProps>) {
|
|
268
|
+
const _onChange = (value: AccountRef) => {
|
|
269
|
+
onChange(value)
|
|
270
|
+
}
|
|
271
|
+
return <SelectBox
|
|
272
|
+
options={accounts}
|
|
273
|
+
value={accounts?.find(a => a.id === value)}
|
|
274
|
+
onChange={_onChange}
|
|
275
|
+
by="id"
|
|
276
|
+
optionLabel={(option) => option.name}
|
|
277
|
+
placeholder='Select Account'
|
|
278
|
+
/>
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
interface SelectProjectProps {
|
|
282
|
+
value?: string
|
|
283
|
+
projects: ProjectRef[]
|
|
284
|
+
onChange: (value: ProjectRef) => void
|
|
285
|
+
}
|
|
286
|
+
function SelectProject({ value, projects, onChange }: Readonly<SelectProjectProps>) {
|
|
287
|
+
const _onChange = (value: ProjectRef) => {
|
|
288
|
+
onChange(value)
|
|
289
|
+
}
|
|
290
|
+
return (
|
|
291
|
+
<SelectBox
|
|
292
|
+
by="id"
|
|
293
|
+
value={projects.find(p => p.id === value)}
|
|
294
|
+
options={projects}
|
|
295
|
+
optionLabel={(option) => option.name}
|
|
296
|
+
placeholder='Select Project'
|
|
297
|
+
onChange={_onChange} />
|
|
298
|
+
)
|
|
299
|
+
}
|