From d64f167b3b9ee953b5542dce6302f801df8435c6 Mon Sep 17 00:00:00 2001 From: Lucas Bordeau Date: Mon, 16 Oct 2023 22:04:41 +0200 Subject: [PATCH] Feat/front temp seed custom objects (#2070) * wip * Fixed bugs * Added flexible backend test --- front/src/generated-metadata/gql.ts | 14 +++- front/src/generated-metadata/graphql.ts | 20 ++++- front/src/generated/graphql.tsx | 3 +- .../components/ClientConfigProvider.tsx | 8 ++ .../graphql/queries/getClientConfig.ts | 1 + .../states/isFlexibleBackendEnabledState.ts | 6 ++ .../components/FetchMetadataEffect.tsx | 40 ++++++++- .../components/ObjectDataTableEffect.tsx | 3 +- .../src/modules/metadata/graphql/mutations.ts | 30 +++++++ .../hooks/useSeedCustomObjectsTemp.ts | 83 +++++++++++++++++++ .../useSetDataTableData.ts | 0 .../modules/metadata/types/MetadataObject.ts | 5 +- server/src/database/seeds/workspaces.ts | 8 +- 13 files changed, 208 insertions(+), 13 deletions(-) create mode 100644 front/src/modules/client-config/states/isFlexibleBackendEnabledState.ts create mode 100644 front/src/modules/metadata/graphql/mutations.ts create mode 100644 front/src/modules/metadata/hooks/useSeedCustomObjectsTemp.ts rename front/src/modules/metadata/{components => hooks}/useSetDataTableData.ts (100%) diff --git a/front/src/generated-metadata/gql.ts b/front/src/generated-metadata/gql.ts index bbab28c99..825de8ba6 100644 --- a/front/src/generated-metadata/gql.ts +++ b/front/src/generated-metadata/gql.ts @@ -13,7 +13,9 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/ * Therefore it is highly recommended to use the babel or swc plugin for production. */ const documents = { - "\n query Objects {\n objects(paging: { first: 100 }) {\n edges {\n node {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n fields(paging: { first: 100 }) {\n edges {\n node {\n id\n type\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n": types.ObjectsDocument, + "\n mutation CreateOneObject($input: CreateOneObjectInput!) {\n createOneObject(input: $input) {\n id\n }\n }\n": types.CreateOneObjectDocument, + "\n mutation CreateOneField($input: CreateOneFieldInput!) {\n createOneField(input: $input) {\n id\n type\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n": types.CreateOneFieldDocument, + "\n query Objects {\n objects(paging: { first: 100 }) {\n edges {\n node {\n id\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n fields(paging: { first: 100 }) {\n edges {\n node {\n id\n type\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n": types.ObjectsDocument, }; /** @@ -33,7 +35,15 @@ export function graphql(source: string): unknown; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query Objects {\n objects(paging: { first: 100 }) {\n edges {\n node {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n fields(paging: { first: 100 }) {\n edges {\n node {\n id\n type\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n"): (typeof documents)["\n query Objects {\n objects(paging: { first: 100 }) {\n edges {\n node {\n id\n dataSourceId\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n fields(paging: { first: 100 }) {\n edges {\n node {\n id\n type\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n"]; +export function graphql(source: "\n mutation CreateOneObject($input: CreateOneObjectInput!) {\n createOneObject(input: $input) {\n id\n }\n }\n"): (typeof documents)["\n mutation CreateOneObject($input: CreateOneObjectInput!) {\n createOneObject(input: $input) {\n id\n }\n }\n"]; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql(source: "\n mutation CreateOneField($input: CreateOneFieldInput!) {\n createOneField(input: $input) {\n id\n type\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n"): (typeof documents)["\n mutation CreateOneField($input: CreateOneFieldInput!) {\n createOneField(input: $input) {\n id\n type\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n"]; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql(source: "\n query Objects {\n objects(paging: { first: 100 }) {\n edges {\n node {\n id\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n fields(paging: { first: 100 }) {\n edges {\n node {\n id\n type\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n"): (typeof documents)["\n query Objects {\n objects(paging: { first: 100 }) {\n edges {\n node {\n id\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n isCustom\n isActive\n createdAt\n updatedAt\n fields(paging: { first: 100 }) {\n edges {\n node {\n id\n type\n nameSingular\n namePlural\n labelSingular\n labelPlural\n description\n icon\n placeholder\n isCustom\n isActive\n isNullable\n createdAt\n updatedAt\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n totalCount\n }\n }\n"]; export function graphql(source: string) { return (documents as any)[source] ?? {}; diff --git a/front/src/generated-metadata/graphql.ts b/front/src/generated-metadata/graphql.ts index 60e7e3b89..e028d40df 100644 --- a/front/src/generated-metadata/graphql.ts +++ b/front/src/generated-metadata/graphql.ts @@ -814,10 +814,26 @@ export type ObjectEdge = { node: Object; }; +export type CreateOneObjectMutationVariables = Exact<{ + input: CreateOneObjectInput; +}>; + + +export type CreateOneObjectMutation = { __typename?: 'Mutation', createOneObject: { __typename?: 'object', id: string } }; + +export type CreateOneFieldMutationVariables = Exact<{ + input: CreateOneFieldInput; +}>; + + +export type CreateOneFieldMutation = { __typename?: 'Mutation', createOneField: { __typename?: 'field', id: string, type: string, nameSingular: string, namePlural: string, labelSingular: string, labelPlural: string, description?: string | null, icon?: string | null, placeholder?: string | null, isCustom: boolean, isActive: boolean, isNullable: boolean, createdAt: any, updatedAt: any } }; + export type ObjectsQueryVariables = Exact<{ [key: string]: never; }>; -export type ObjectsQuery = { __typename?: 'Query', objects: { __typename?: 'ObjectConnection', totalCount: number, edges: Array<{ __typename?: 'objectEdge', node: { __typename?: 'object', id: string, dataSourceId: string, nameSingular: string, namePlural: string, labelSingular: string, labelPlural: string, description?: string | null, icon?: string | null, isCustom: boolean, isActive: boolean, createdAt: any, updatedAt: any, fields: { __typename?: 'ObjectFieldsConnection', totalCount: number, edges: Array<{ __typename?: 'fieldEdge', node: { __typename?: 'field', id: string, type: string, nameSingular: string, namePlural: string, labelSingular: string, labelPlural: string, description?: string | null, icon?: string | null, placeholder?: string | null, isCustom: boolean, isActive: boolean, isNullable: boolean, createdAt: any, updatedAt: any } }>, pageInfo: { __typename?: 'PageInfo', hasNextPage?: boolean | null, hasPreviousPage?: boolean | null, startCursor?: any | null, endCursor?: any | null } } } }>, pageInfo: { __typename?: 'PageInfo', hasNextPage?: boolean | null, hasPreviousPage?: boolean | null, startCursor?: any | null, endCursor?: any | null } } }; +export type ObjectsQuery = { __typename?: 'Query', objects: { __typename?: 'ObjectConnection', totalCount: number, edges: Array<{ __typename?: 'objectEdge', node: { __typename?: 'object', id: string, nameSingular: string, namePlural: string, labelSingular: string, labelPlural: string, description?: string | null, icon?: string | null, isCustom: boolean, isActive: boolean, createdAt: any, updatedAt: any, fields: { __typename?: 'ObjectFieldsConnection', totalCount: number, edges: Array<{ __typename?: 'fieldEdge', node: { __typename?: 'field', id: string, type: string, nameSingular: string, namePlural: string, labelSingular: string, labelPlural: string, description?: string | null, icon?: string | null, placeholder?: string | null, isCustom: boolean, isActive: boolean, isNullable: boolean, createdAt: any, updatedAt: any } }>, pageInfo: { __typename?: 'PageInfo', hasNextPage?: boolean | null, hasPreviousPage?: boolean | null, startCursor?: any | null, endCursor?: any | null } } } }>, pageInfo: { __typename?: 'PageInfo', hasNextPage?: boolean | null, hasPreviousPage?: boolean | null, startCursor?: any | null, endCursor?: any | null } } }; -export const ObjectsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Objects"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"objects"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"paging"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"first"},"value":{"kind":"IntValue","value":"100"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"dataSourceId"}},{"kind":"Field","name":{"kind":"Name","value":"nameSingular"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}},{"kind":"Field","name":{"kind":"Name","value":"labelSingular"}},{"kind":"Field","name":{"kind":"Name","value":"labelPlural"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"fields"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"paging"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"first"},"value":{"kind":"IntValue","value":"100"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"nameSingular"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}},{"kind":"Field","name":{"kind":"Name","value":"labelSingular"}},{"kind":"Field","name":{"kind":"Name","value":"labelPlural"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"placeholder"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"isNullable"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}},{"kind":"Field","name":{"kind":"Name","value":"hasPreviousPage"}},{"kind":"Field","name":{"kind":"Name","value":"startCursor"}},{"kind":"Field","name":{"kind":"Name","value":"endCursor"}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}},{"kind":"Field","name":{"kind":"Name","value":"hasPreviousPage"}},{"kind":"Field","name":{"kind":"Name","value":"startCursor"}},{"kind":"Field","name":{"kind":"Name","value":"endCursor"}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file +export const CreateOneObjectDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOneObject"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateOneObjectInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createOneObject"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; +export const CreateOneFieldDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOneField"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateOneFieldInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createOneField"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"nameSingular"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}},{"kind":"Field","name":{"kind":"Name","value":"labelSingular"}},{"kind":"Field","name":{"kind":"Name","value":"labelPlural"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"placeholder"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"isNullable"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; +export const ObjectsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Objects"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"objects"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"paging"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"first"},"value":{"kind":"IntValue","value":"100"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"nameSingular"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}},{"kind":"Field","name":{"kind":"Name","value":"labelSingular"}},{"kind":"Field","name":{"kind":"Name","value":"labelPlural"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"fields"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"paging"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"first"},"value":{"kind":"IntValue","value":"100"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"nameSingular"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}},{"kind":"Field","name":{"kind":"Name","value":"labelSingular"}},{"kind":"Field","name":{"kind":"Name","value":"labelPlural"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"placeholder"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"isNullable"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}},{"kind":"Field","name":{"kind":"Name","value":"hasPreviousPage"}},{"kind":"Field","name":{"kind":"Name","value":"startCursor"}},{"kind":"Field","name":{"kind":"Name","value":"endCursor"}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}},{"kind":"Field","name":{"kind":"Name","value":"hasPreviousPage"}},{"kind":"Field","name":{"kind":"Name","value":"startCursor"}},{"kind":"Field","name":{"kind":"Name","value":"endCursor"}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/front/src/generated/graphql.tsx b/front/src/generated/graphql.tsx index dffa4951e..9120f03bd 100644 --- a/front/src/generated/graphql.tsx +++ b/front/src/generated/graphql.tsx @@ -3737,7 +3737,7 @@ export type CheckUserExistsQuery = { __typename?: 'Query', checkUserExists: { __ export type GetClientConfigQueryVariables = Exact<{ [key: string]: never; }>; -export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', signInPrefilled: boolean, debugMode: boolean, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean }, telemetry: { __typename?: 'Telemetry', enabled: boolean, anonymizationEnabled: boolean }, support: { __typename?: 'Support', supportDriver: string, supportFrontChatId?: string | null } } }; +export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', signInPrefilled: boolean, debugMode: boolean, flexibleBackendEnabled: boolean, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean }, telemetry: { __typename?: 'Telemetry', enabled: boolean, anonymizationEnabled: boolean }, support: { __typename?: 'Support', supportDriver: string, supportFrontChatId?: string | null } } }; export type BaseCompanyFieldsFragmentFragment = { __typename?: 'Company', address: string, annualRecurringRevenue?: number | null, createdAt: string, domainName: string, employees?: number | null, id: string, idealCustomerProfile: boolean, linkedinUrl?: string | null, name: string, xUrl?: string | null, _activityCount: number }; @@ -5189,6 +5189,7 @@ export const GetClientConfigDocument = gql` supportDriver supportFrontChatId } + flexibleBackendEnabled } } `; diff --git a/front/src/modules/client-config/components/ClientConfigProvider.tsx b/front/src/modules/client-config/components/ClientConfigProvider.tsx index e0dd36666..be71a8ad4 100644 --- a/front/src/modules/client-config/components/ClientConfigProvider.tsx +++ b/front/src/modules/client-config/components/ClientConfigProvider.tsx @@ -8,11 +8,17 @@ import { supportChatState } from '@/client-config/states/supportChatState'; import { telemetryState } from '@/client-config/states/telemetryState'; import { useGetClientConfigQuery } from '~/generated/graphql'; +import { isFlexibleBackendEnabledState } from '../states/isFlexibleBackendEnabledState'; + export const ClientConfigProvider: React.FC = ({ children, }) => { const [, setAuthProviders] = useRecoilState(authProvidersState); const [, setIsDebugMode] = useRecoilState(isDebugModeState); + const [, setIsFlexibleBackendEnabled] = useRecoilState( + isFlexibleBackendEnabledState, + ); + const [, setIsSignInPrefilled] = useRecoilState(isSignInPrefilledState); const [, setTelemetry] = useRecoilState(telemetryState); const [isLoading, setIsLoading] = useState(true); @@ -30,6 +36,7 @@ export const ClientConfigProvider: React.FC = ({ password: data?.clientConfig.authProviders.password, magicLink: false, }); + setIsFlexibleBackendEnabled(data?.clientConfig.flexibleBackendEnabled); setIsDebugMode(data?.clientConfig.debugMode); setIsSignInPrefilled(data?.clientConfig.signInPrefilled); setTelemetry(data?.clientConfig.telemetry); @@ -39,6 +46,7 @@ export const ClientConfigProvider: React.FC = ({ data, setAuthProviders, setIsDebugMode, + setIsFlexibleBackendEnabled, setIsSignInPrefilled, setTelemetry, setIsLoading, diff --git a/front/src/modules/client-config/graphql/queries/getClientConfig.ts b/front/src/modules/client-config/graphql/queries/getClientConfig.ts index a5502c901..59b439a2b 100644 --- a/front/src/modules/client-config/graphql/queries/getClientConfig.ts +++ b/front/src/modules/client-config/graphql/queries/getClientConfig.ts @@ -17,6 +17,7 @@ export const GET_CLIENT_CONFIG = gql` supportDriver supportFrontChatId } + flexibleBackendEnabled } } `; diff --git a/front/src/modules/client-config/states/isFlexibleBackendEnabledState.ts b/front/src/modules/client-config/states/isFlexibleBackendEnabledState.ts new file mode 100644 index 000000000..7cbf72322 --- /dev/null +++ b/front/src/modules/client-config/states/isFlexibleBackendEnabledState.ts @@ -0,0 +1,6 @@ +import { atom } from 'recoil'; + +export const isFlexibleBackendEnabledState = atom({ + key: 'isFlexibleBackendEnabledState', + default: false, +}); diff --git a/front/src/modules/metadata/components/FetchMetadataEffect.tsx b/front/src/modules/metadata/components/FetchMetadataEffect.tsx index d4ff6b642..54e9668bb 100644 --- a/front/src/modules/metadata/components/FetchMetadataEffect.tsx +++ b/front/src/modules/metadata/components/FetchMetadataEffect.tsx @@ -1,20 +1,28 @@ import { useEffect } from 'react'; import { useRecoilState } from 'recoil'; +import { isFlexibleBackendEnabledState } from '@/client-config/states/isFlexibleBackendEnabledState'; import { ObjectsQuery } from '~/generated-metadata/graphql'; import { GET_ALL_OBJECTS } from '../graphql/queries'; import { useApolloClientMetadata } from '../hooks/useApolloClientMetadata'; +import { useSeedCustomObjectsTemp } from '../hooks/useSeedCustomObjectsTemp'; import { metadataObjectsState } from '../states/metadataObjectsState'; import { MetadataObject } from '../types/MetadataObject'; export const FetchMetadataEffect = () => { const [metadataObjects, setMetadataObjects] = useRecoilState(metadataObjectsState); - + const [isFlexibleBackendEnabled] = useRecoilState( + isFlexibleBackendEnabledState, + ); const apolloClientMetadata = useApolloClientMetadata(); + const seedCustomObjectsTemp = useSeedCustomObjectsTemp(); + useEffect(() => { + if (!isFlexibleBackendEnabled) return; + (async () => { if (apolloClientMetadata && metadataObjects.length === 0) { const objects = await apolloClientMetadata.query({ @@ -31,10 +39,38 @@ export const FetchMetadataEffect = () => { fields: object.node.fields.edges.map((field) => field.node), })); setMetadataObjects(formattedObjects); + } else if ( + objects.data.objects.edges.length === 0 && + metadataObjects.length === 0 + ) { + try { + await seedCustomObjectsTemp(); + + const objects = await apolloClientMetadata.query({ + query: GET_ALL_OBJECTS, + }); + + const formattedObjects: MetadataObject[] = + objects.data.objects.edges.map((object) => ({ + ...object.node, + fields: object.node.fields.edges.map((field) => field.node), + })); + + setMetadataObjects(formattedObjects); + } catch (error) { + // eslint-disable-next-line no-console + console.log(error); + } } } })(); - }, [metadataObjects, setMetadataObjects, apolloClientMetadata]); + }, [ + isFlexibleBackendEnabled, + metadataObjects, + setMetadataObjects, + apolloClientMetadata, + seedCustomObjectsTemp, + ]); return <>; }; diff --git a/front/src/modules/metadata/components/ObjectDataTableEffect.tsx b/front/src/modules/metadata/components/ObjectDataTableEffect.tsx index 78d630fcf..c40f7391c 100644 --- a/front/src/modules/metadata/components/ObjectDataTableEffect.tsx +++ b/front/src/modules/metadata/components/ObjectDataTableEffect.tsx @@ -11,8 +11,7 @@ import { sortsScopedState } from '@/ui/data/view-bar/states/sortsScopedState'; import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId'; import { useFindManyCustomObjects } from '../hooks/useFindManyCustomObjects'; - -import { useSetObjectDataTableData } from './useSetDataTableData'; +import { useSetObjectDataTableData } from '../hooks/useSetDataTableData'; export const ObjectDataTableEffect = ({ objectName, diff --git a/front/src/modules/metadata/graphql/mutations.ts b/front/src/modules/metadata/graphql/mutations.ts new file mode 100644 index 000000000..ff541cef9 --- /dev/null +++ b/front/src/modules/metadata/graphql/mutations.ts @@ -0,0 +1,30 @@ +import { gql } from '@apollo/client'; + +export const CREATE_ONE_OBJECT = gql` + mutation CreateOneObject($input: CreateOneObjectInput!) { + createOneObject(input: $input) { + id + } + } +`; + +export const CREATE_ONE_FIELD = gql` + mutation CreateOneField($input: CreateOneFieldInput!) { + createOneField(input: $input) { + id + type + nameSingular + namePlural + labelSingular + labelPlural + description + icon + placeholder + isCustom + isActive + isNullable + createdAt + updatedAt + } + } +`; diff --git a/front/src/modules/metadata/hooks/useSeedCustomObjectsTemp.ts b/front/src/modules/metadata/hooks/useSeedCustomObjectsTemp.ts new file mode 100644 index 000000000..9a80ced86 --- /dev/null +++ b/front/src/modules/metadata/hooks/useSeedCustomObjectsTemp.ts @@ -0,0 +1,83 @@ +import { + CreateOneFieldMutation, + CreateOneFieldMutationVariables, + CreateOneObjectMutation, + CreateOneObjectMutationVariables, +} from '~/generated-metadata/graphql'; + +import { CREATE_ONE_FIELD, CREATE_ONE_OBJECT } from '../graphql/mutations'; + +import { useApolloClientMetadata } from './useApolloClientMetadata'; + +export const useSeedCustomObjectsTemp = () => { + const client = useApolloClientMetadata(); + + return async () => { + if (!client) return; + + const { data: createSuppliersData } = await client?.mutate< + CreateOneObjectMutation, + CreateOneObjectMutationVariables + >({ + mutation: CREATE_ONE_OBJECT, + variables: { + input: { + object: { + labelPlural: 'Suppliers', + labelSingular: 'Supplier', + nameSingular: 'supplier', + namePlural: 'suppliers', + description: 'Suppliers', + icon: 'IconBuilding', + }, + }, + }, + }); + + const supplierObjectId = createSuppliersData?.createOneObject?.id ?? ''; + + await client?.mutate< + CreateOneFieldMutation, + CreateOneFieldMutationVariables + >({ + mutation: CREATE_ONE_FIELD, + variables: { + input: { + field: { + objectId: supplierObjectId, + labelSingular: 'Name', + nameSingular: 'name', + type: 'text', + description: 'Name', + labelPlural: 'Names', + namePlural: 'names', + placeholder: 'Name', + icon: 'IconBuilding', + }, + }, + }, + }); + + await client?.mutate< + CreateOneFieldMutation, + CreateOneFieldMutationVariables + >({ + mutation: CREATE_ONE_FIELD, + variables: { + input: { + field: { + objectId: supplierObjectId, + labelSingular: 'City', + nameSingular: 'city', + type: 'text', + description: 'City', + labelPlural: 'Cities', + namePlural: 'cities', + placeholder: 'City', + icon: 'IconMap', + }, + }, + }, + }); + }; +}; diff --git a/front/src/modules/metadata/components/useSetDataTableData.ts b/front/src/modules/metadata/hooks/useSetDataTableData.ts similarity index 100% rename from front/src/modules/metadata/components/useSetDataTableData.ts rename to front/src/modules/metadata/hooks/useSetDataTableData.ts diff --git a/front/src/modules/metadata/types/MetadataObject.ts b/front/src/modules/metadata/types/MetadataObject.ts index 6d4577bbb..1807c93ee 100644 --- a/front/src/modules/metadata/types/MetadataObject.ts +++ b/front/src/modules/metadata/types/MetadataObject.ts @@ -1,5 +1,8 @@ import { Field, Object as GeneratedObject } from '~/generated-metadata/graphql'; -export type MetadataObject = Omit & { +export type MetadataObject = Omit< + GeneratedObject, + 'fields' | 'dataSourceId' +> & { fields: Field[]; }; diff --git a/server/src/database/seeds/workspaces.ts b/server/src/database/seeds/workspaces.ts index 47384d6a7..025dbcbb4 100644 --- a/server/src/database/seeds/workspaces.ts +++ b/server/src/database/seeds/workspaces.ts @@ -42,17 +42,19 @@ export const seedWorkspaces = async (prisma: PrismaClient) => { ); `); - await prisma.$queryRawUnsafe('CREATE SCHEMA IF NOT EXISTS workspace_apple'); + await prisma.$queryRawUnsafe( + 'CREATE SCHEMA IF NOT EXISTS workspace_twenty_7icsva0r6s00mpcp6cwg4w4rd', + ); await prisma.$queryRawUnsafe( `INSERT INTO metadata.data_source_metadata( id, schema, type, workspace_id ) VALUES ( - 'b37b2163-7f63-47a9-b1b3-6c7290ca9fb1', 'workspace_apple', 'postgres', 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419' + 'b37b2163-7f63-47a9-b1b3-6c7290ca9fb1', 'workspace_twenty_7icsva0r6s00mpcp6cwg4w4rd', 'postgres', 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419' ) ON CONFLICT DO NOTHING`, ); await prisma.$queryRawUnsafe(` - CREATE TABLE IF NOT EXISTS workspace_apple.tenant_migrations ( + CREATE TABLE IF NOT EXISTS workspace_twenty_7icsva0r6s00mpcp6cwg4w4rd.tenant_migrations ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, migrations JSONB, applied_at TIMESTAMP NULL,