From 59efbc2e93f55acd2596d46f28dab12ebdda63e0 Mon Sep 17 00:00:00 2001 From: Harish Mohan Raj Date: Tue, 17 Sep 2024 10:19:23 +0530 Subject: [PATCH 1/2] Update auth callout packages (#729) --- auth_callout/package.json | 6 +-- .../packages/auth-service/package.json | 2 +- auth_callout/pnpm-lock.yaml | 50 +++++++++---------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/auth_callout/package.json b/auth_callout/package.json index 05929753..190911c3 100644 --- a/auth_callout/package.json +++ b/auth_callout/package.json @@ -6,9 +6,9 @@ "packages/*" ], "devDependencies": { - "tsx": "^4.19.0", - "typescript": "^5.5.4", - "vite": "^5.4.3", + "tsx": "^4.19.1", + "typescript": "^5.6.2", + "vite": "^5.4.5", "vite-plugin-checker": "^0.8.0" }, "scripts": { diff --git a/auth_callout/packages/auth-service/package.json b/auth_callout/packages/auth-service/package.json index 311899a0..19da2131 100644 --- a/auth_callout/packages/auth-service/package.json +++ b/auth_callout/packages/auth-service/package.json @@ -8,7 +8,7 @@ "type": "module", "main": "./lib/index.js", "devDependencies": { - "@types/node": "^22.5.3" + "@types/node": "^22.5.5" }, "dependencies": { "@prisma/client": "^5.19.0", diff --git a/auth_callout/pnpm-lock.yaml b/auth_callout/pnpm-lock.yaml index 5c7cc6ab..a20b9701 100644 --- a/auth_callout/pnpm-lock.yaml +++ b/auth_callout/pnpm-lock.yaml @@ -9,17 +9,17 @@ importers: .: devDependencies: tsx: - specifier: ^4.19.0 - version: 4.19.0 + specifier: ^4.19.1 + version: 4.19.1 typescript: - specifier: ^5.5.4 - version: 5.5.4 + specifier: ^5.6.2 + version: 5.6.2 vite: - specifier: ^5.4.3 - version: 5.4.3(@types/node@22.5.4) + specifier: ^5.4.5 + version: 5.4.6(@types/node@22.5.5) vite-plugin-checker: specifier: ^0.8.0 - version: 0.8.0(typescript@5.5.4)(vite@5.4.3(@types/node@22.5.4)) + version: 0.8.0(typescript@5.6.2)(vite@5.4.6(@types/node@22.5.5)) packages/auth-service: dependencies: @@ -40,8 +40,8 @@ importers: version: 5.19.1 devDependencies: '@types/node': - specifier: ^22.5.3 - version: 22.5.4 + specifier: ^22.5.5 + version: 22.5.5 packages: @@ -458,8 +458,8 @@ packages: '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - '@types/node@22.5.4': - resolution: {integrity: sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==} + '@types/node@22.5.5': + resolution: {integrity: sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==} ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} @@ -710,8 +710,8 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - tsx@4.19.0: - resolution: {integrity: sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==} + tsx@4.19.1: + resolution: {integrity: sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==} engines: {node: '>=18.0.0'} hasBin: true @@ -722,8 +722,8 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + typescript@5.6.2: + resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==} engines: {node: '>=14.17'} hasBin: true @@ -768,8 +768,8 @@ packages: vue-tsc: optional: true - vite@5.4.3: - resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==} + vite@5.4.6: + resolution: {integrity: sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -1069,7 +1069,7 @@ snapshots: '@types/estree@1.0.5': {} - '@types/node@22.5.4': + '@types/node@22.5.5': dependencies: undici-types: 6.19.8 @@ -1371,7 +1371,7 @@ snapshots: dependencies: is-number: 7.0.0 - tsx@4.19.0: + tsx@4.19.1: dependencies: esbuild: 0.23.1 get-tsconfig: 4.7.6 @@ -1382,13 +1382,13 @@ snapshots: type-fest@0.21.3: {} - typescript@5.5.4: {} + typescript@5.6.2: {} undici-types@6.19.8: {} universalify@2.0.1: {} - vite-plugin-checker@0.8.0(typescript@5.5.4)(vite@5.4.3(@types/node@22.5.4)): + vite-plugin-checker@0.8.0(typescript@5.6.2)(vite@5.4.6(@types/node@22.5.5)): dependencies: '@babel/code-frame': 7.22.13 ansi-escapes: 4.3.2 @@ -1400,21 +1400,21 @@ snapshots: npm-run-path: 4.0.1 strip-ansi: 6.0.1 tiny-invariant: 1.3.1 - vite: 5.4.3(@types/node@22.5.4) + vite: 5.4.6(@types/node@22.5.5) vscode-languageclient: 7.0.0 vscode-languageserver: 7.0.0 vscode-languageserver-textdocument: 1.0.11 vscode-uri: 3.0.8 optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.2 - vite@5.4.3(@types/node@22.5.4): + vite@5.4.6(@types/node@22.5.5): dependencies: esbuild: 0.21.5 postcss: 8.4.45 rollup: 4.21.1 optionalDependencies: - '@types/node': 22.5.4 + '@types/node': 22.5.5 fsevents: 2.3.3 vscode-jsonrpc@6.0.0: {} From 99ea194143c7732c807039c4465521bd779c84fe Mon Sep 17 00:00:00 2001 From: Harish Mohan Raj Date: Tue, 17 Sep 2024 19:32:57 +0530 Subject: [PATCH 2/2] Mark specific form fields as non-editable while editing the property (#723) * WIP * WIP * WIP * WIP * Polishing and code refactoring * Add tooltips * Fix pre-commit errors * Polishing --- app/src/client/App.tsx | 16 +- .../components/buildPage/DynamicForm.tsx | 119 ++-- .../client/components/buildPage/FormField.tsx | 27 +- .../buildPage/PropertySchemaParser.ts | 12 + .../buildPage/usePropertyManager.ts | 5 +- app/src/client/components/form/TextArea.tsx | 6 +- app/src/client/components/form/TextInput.tsx | 6 +- .../client/interfaces/BuildPageInterfaces.ts | 1 + .../client/tests/PropertySchemaParser.test.ts | 37 +- .../client/tests/UserProperty-e2e.test.tsx | 132 +++- app/src/client/tests/mocks.ts | 616 +++++++++++++++++- app/src/client/utils/constants.ts | 3 +- app/tailwind.config.cjs | 2 + 13 files changed, 909 insertions(+), 73 deletions(-) diff --git a/app/src/client/App.tsx b/app/src/client/App.tsx index 1671beb4..d31a57b4 100644 --- a/app/src/client/App.tsx +++ b/app/src/client/App.tsx @@ -1,5 +1,6 @@ import { useMemo, useEffect, ReactNode, useState } from 'react'; import { useLocation } from 'react-router-dom'; +import { ChakraProvider, extendTheme } from '@chakra-ui/react'; import './Main.css'; @@ -12,6 +13,17 @@ import ServerNotRechableComponent from './components/ServerNotRechableComponent' import LoadingComponent from './components/LoadingComponent'; import TosAndMarketingEmailsModal from './components/TosAndMarketingEmailsModal'; +const theme = extendTheme({ + colors: { + brand: { + airtPrimary: '#003257', + }, + }, + zIndices: { + tooltip: 10000, + }, +}); + const addServerErrorClass = () => { if (!document.body.classList.contains('server-error')) { document.body.classList.add('server-error'); @@ -114,7 +126,7 @@ export default function App({ children }: { children: ReactNode }) { }, [location]); return ( - <> +
{isError && (addServerErrorClass(), ())} {isAdminDashboard || isPlayGroundPage || isBuildPage ? ( @@ -153,7 +165,7 @@ export default function App({ children }: { children: ReactNode }) {
)} - +
); } diff --git a/app/src/client/components/buildPage/DynamicForm.tsx b/app/src/client/components/buildPage/DynamicForm.tsx index 30fba07c..9c40fec9 100644 --- a/app/src/client/components/buildPage/DynamicForm.tsx +++ b/app/src/client/components/buildPage/DynamicForm.tsx @@ -75,6 +75,18 @@ export const DynamicForm: React.FC = ({ popFromStackWithFormState, } = usePropertyManager(parser, updateFormStack, refetchUserProperties, popFromStack); + const propertyName = parser?.getPropertyName() || ''; + const isDeploymentProperty = propertyName === 'deployment'; + + const flow = parser?.getFlow(); + const isAddModelFlow = flow === Flow.ADD_MODEL; + const isUpdateModelFlow = flow === Flow.UPDATE_MODEL; + + const shouldShowDeploymentPrerequisites = isDeploymentProperty && isAddModelFlow && !successResponse; + const isDeploymentCreatedSuccessfully = isDeploymentProperty && isAddModelFlow && successResponse; + const shouldShowDeploymentInstructions = isDeploymentProperty && isUpdateModelFlow; + const checkForImmutableFields = isDeploymentCreatedSuccessfully || isUpdateModelFlow; + const addPropertyHandler = (modelName: string, propertyName: string, fieldKey: string) => { popFromStackWithFormState(modelName, propertyName, fieldKey); }; @@ -87,17 +99,26 @@ export const DynamicForm: React.FC = ({ } const isReferenceField = parser?.checkIfRefField(property); let propertyCopy = Object.assign({}, property); + let isOptionalRefField = false; if (isReferenceField) { const refFields = parser?.getRefFields(); if (refFields && refFields[key]) { propertyCopy = refFields[key].htmlForSelectBox; isOptionalRefField = refFields[key].isOptional; + const metadata = refFields[key]?.metadata; + if (metadata) { + propertyCopy.metadata = metadata; + } } } else { const isNonRefButDropDownFields = parser?.getNonRefButDropdownFields(); if (isNonRefButDropDownFields && isNonRefButDropDownFields[key]) { propertyCopy = isNonRefButDropDownFields[key].htmlForSelectBox; + const metadata = isNonRefButDropDownFields[key]?.metadata; + if (metadata) { + propertyCopy.metadata = metadata; + } } } return ( @@ -111,6 +132,7 @@ export const DynamicForm: React.FC = ({ fieldKey={key} isOptionalRefField={isOptionalRefField} addPropertyHandler={addPropertyHandler} + checkForImmutableFields={checkForImmutableFields} /> )} validators={{ @@ -122,7 +144,7 @@ export const DynamicForm: React.FC = ({ } else { return null; } - }, [schema, form]); + }, [schema, form, checkForImmutableFields]); const cancelButtonRef = useRef(null); useEscapeKeyHandler(cancelButtonRef); @@ -131,12 +153,6 @@ export const DynamicForm: React.FC = ({ setNotification(null); }; - const propertyName = parser?.getPropertyName() || ''; - const isDeploymentProperty = propertyName === 'deployment'; - - const flow = parser?.getFlow(); - const isAddUserFlow = flow === Flow.ADD_MODEL; - return (
{ @@ -148,56 +164,55 @@ export const DynamicForm: React.FC = ({ {isLoading && } {notification && } - {isDeploymentProperty && isAddUserFlow && !successResponse && ( - - )} + {shouldShowDeploymentPrerequisites && } {formFields} - {isDeploymentProperty && isAddUserFlow && successResponse && ( - - )} - {isDeploymentProperty && !isAddUserFlow && } + {isDeploymentCreatedSuccessfully && } + {shouldShowDeploymentInstructions && } [state.canSubmit, state.isSubmitting]} - children={([canSubmit, isSubmitting]) => ( - <> - {isSubmitting && } -
-
- - + children={([canSubmit, isSubmitting]) => { + const disableSaveButton = !canSubmit || isDeploymentCreatedSuccessfully; + return ( + <> + {isSubmitting && } +
+
+ + +
+ {parser?.getFlow() === 'update_model' && ( + + )}
- {parser?.getFlow() === 'update_model' && ( - - )} -
- - )} + + ); + }} /> ); diff --git a/app/src/client/components/buildPage/FormField.tsx b/app/src/client/components/buildPage/FormField.tsx index b48706ce..757cabfa 100644 --- a/app/src/client/components/buildPage/FormField.tsx +++ b/app/src/client/components/buildPage/FormField.tsx @@ -2,6 +2,8 @@ import React, { useEffect, useState } from 'react'; import _ from 'lodash'; import { FieldApi } from '@tanstack/react-form'; import Select, { StylesConfig } from 'react-select'; +import { Tooltip } from '@chakra-ui/react'; +import { IoIosInformationCircleOutline } from 'react-icons/io'; import { TextInput } from '../form/TextInput'; import { SECRETS_TO_MASK } from '../../utils/constants'; @@ -37,6 +39,7 @@ interface FormFieldProps { fieldKey: string; isOptionalRefField: boolean; addPropertyHandler: AddPropertyHandler; + checkForImmutableFields: boolean; } function FieldInfo({ field }: { field: FieldApi }) { @@ -62,6 +65,7 @@ export const FormField: React.FC = ({ fieldKey, isOptionalRefField, addPropertyHandler, + checkForImmutableFields, }) => { const [selectOptions, setSelectOptions] = useState([]); const [defaultValue, setDefaultValue] = useState(null); @@ -103,9 +107,27 @@ export const FormField: React.FC = ({ } }; + const immutableAfterCreation = checkForImmutableFields && property.metadata?.immutable_after_creation; + const toolTipMessage = property.metadata?.tooltip_message; + return (
- + {property.enum ? (