Migrate to a monorepo structure (#2909)
This commit is contained in:
@ -0,0 +1,9 @@
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { ApolloMetadataClientContext } from '../context/ApolloClientMetadataContext';
|
||||
|
||||
export const useApolloMetadataClient = () => {
|
||||
const apolloMetadataClient = useContext(ApolloMetadataClientContext);
|
||||
|
||||
return apolloMetadataClient;
|
||||
};
|
||||
@ -0,0 +1,52 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
|
||||
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
import { Nullable } from '~/types/Nullable';
|
||||
|
||||
import { formatFieldMetadataItemAsColumnDefinition } from '../utils/formatFieldMetadataItemAsColumnDefinition';
|
||||
import { formatFieldMetadataItemsAsFilterDefinitions } from '../utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { formatFieldMetadataItemsAsSortDefinitions } from '../utils/formatFieldMetadataItemsAsSortDefinitions';
|
||||
|
||||
export const useColumnDefinitionsFromFieldMetadata = (
|
||||
objectMetadataItem?: Nullable<ObjectMetadataItem>,
|
||||
) => {
|
||||
const activeFieldMetadataItems = useMemo(
|
||||
() =>
|
||||
objectMetadataItem
|
||||
? objectMetadataItem.fields.filter(
|
||||
({ isActive, isSystem }) => isActive && !isSystem,
|
||||
)
|
||||
: [],
|
||||
[objectMetadataItem],
|
||||
);
|
||||
|
||||
const columnDefinitions: ColumnDefinition<FieldMetadata>[] = useMemo(
|
||||
() =>
|
||||
objectMetadataItem
|
||||
? activeFieldMetadataItems.map((field, index) =>
|
||||
formatFieldMetadataItemAsColumnDefinition({
|
||||
position: index,
|
||||
field,
|
||||
objectMetadataItem,
|
||||
}),
|
||||
)
|
||||
: [],
|
||||
[activeFieldMetadataItems, objectMetadataItem],
|
||||
);
|
||||
|
||||
const filterDefinitions = formatFieldMetadataItemsAsFilterDefinitions({
|
||||
fields: activeFieldMetadataItems,
|
||||
});
|
||||
|
||||
const sortDefinitions = formatFieldMetadataItemsAsSortDefinitions({
|
||||
fields: activeFieldMetadataItems,
|
||||
});
|
||||
|
||||
return {
|
||||
columnDefinitions,
|
||||
filterDefinitions,
|
||||
sortDefinitions,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,53 @@
|
||||
import { ApolloClient, useMutation } from '@apollo/client';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
|
||||
import { FieldType } from '@/object-record/field/types/FieldType';
|
||||
import {
|
||||
CreateOneFieldMetadataItemMutation,
|
||||
CreateOneFieldMetadataItemMutationVariables,
|
||||
FieldMetadataType,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { CREATE_ONE_FIELD_METADATA_ITEM } from '../graphql/mutations';
|
||||
import { FIND_MANY_OBJECT_METADATA_ITEMS } from '../graphql/queries';
|
||||
|
||||
import { useApolloMetadataClient } from './useApolloMetadataClient';
|
||||
|
||||
type CreateOneFieldMetadataItemArgs = Omit<
|
||||
CreateOneFieldMetadataItemMutationVariables['input']['field'],
|
||||
'type'
|
||||
> & {
|
||||
type: FieldType;
|
||||
};
|
||||
|
||||
export const useCreateOneFieldMetadataItem = () => {
|
||||
const apolloMetadataClient = useApolloMetadataClient();
|
||||
|
||||
const [mutate] = useMutation<
|
||||
CreateOneFieldMetadataItemMutation,
|
||||
CreateOneFieldMetadataItemMutationVariables
|
||||
>(CREATE_ONE_FIELD_METADATA_ITEM, {
|
||||
client: apolloMetadataClient ?? ({} as ApolloClient<any>),
|
||||
});
|
||||
|
||||
const createOneFieldMetadataItem = async (
|
||||
input: CreateOneFieldMetadataItemArgs,
|
||||
) => {
|
||||
return await mutate({
|
||||
variables: {
|
||||
input: {
|
||||
field: {
|
||||
...input,
|
||||
type: input.type as FieldMetadataType, // Todo improve typing once we have aligned backend and frontend
|
||||
},
|
||||
},
|
||||
},
|
||||
awaitRefetchQueries: true,
|
||||
refetchQueries: [getOperationName(FIND_MANY_OBJECT_METADATA_ITEMS) ?? ''],
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
createOneFieldMetadataItem,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,43 @@
|
||||
import { ApolloClient, useMutation } from '@apollo/client';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
|
||||
import {
|
||||
CreateOneObjectMetadataItemMutation,
|
||||
CreateOneObjectMetadataItemMutationVariables,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { CREATE_ONE_OBJECT_METADATA_ITEM } from '../graphql/mutations';
|
||||
import { FIND_MANY_OBJECT_METADATA_ITEMS } from '../graphql/queries';
|
||||
|
||||
import { useApolloMetadataClient } from './useApolloMetadataClient';
|
||||
|
||||
export const useCreateOneObjectRecordMetadataItem = () => {
|
||||
const apolloMetadataClient = useApolloMetadataClient();
|
||||
|
||||
const [mutate] = useMutation<
|
||||
CreateOneObjectMetadataItemMutation,
|
||||
CreateOneObjectMetadataItemMutationVariables
|
||||
>(CREATE_ONE_OBJECT_METADATA_ITEM, {
|
||||
client: apolloMetadataClient ?? ({} as ApolloClient<any>),
|
||||
});
|
||||
|
||||
const createOneObjectMetadataItem = async (
|
||||
input: CreateOneObjectMetadataItemMutationVariables['input']['object'],
|
||||
) => {
|
||||
return await mutate({
|
||||
variables: {
|
||||
input: {
|
||||
object: {
|
||||
...input,
|
||||
},
|
||||
},
|
||||
},
|
||||
awaitRefetchQueries: true,
|
||||
refetchQueries: [getOperationName(FIND_MANY_OBJECT_METADATA_ITEMS) ?? ''],
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
createOneObjectMetadataItem,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,41 @@
|
||||
import { ApolloClient, useMutation } from '@apollo/client';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
|
||||
import {
|
||||
CreateOneRelationMetadataMutation,
|
||||
CreateOneRelationMetadataMutationVariables,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { CREATE_ONE_RELATION_METADATA_ITEM } from '../graphql/mutations';
|
||||
import { FIND_MANY_OBJECT_METADATA_ITEMS } from '../graphql/queries';
|
||||
import {
|
||||
formatRelationMetadataInput,
|
||||
FormatRelationMetadataInputParams,
|
||||
} from '../utils/formatRelationMetadataInput';
|
||||
|
||||
import { useApolloMetadataClient } from './useApolloMetadataClient';
|
||||
|
||||
export const useCreateOneRelationMetadataItem = () => {
|
||||
const apolloMetadataClient = useApolloMetadataClient();
|
||||
|
||||
const [mutate] = useMutation<
|
||||
CreateOneRelationMetadataMutation,
|
||||
CreateOneRelationMetadataMutationVariables
|
||||
>(CREATE_ONE_RELATION_METADATA_ITEM, {
|
||||
client: apolloMetadataClient ?? ({} as ApolloClient<any>),
|
||||
});
|
||||
|
||||
const createOneRelationMetadataItem = async (
|
||||
input: FormatRelationMetadataInputParams,
|
||||
) => {
|
||||
return await mutate({
|
||||
variables: { input: { relation: formatRelationMetadataInput(input) } },
|
||||
awaitRefetchQueries: true,
|
||||
refetchQueries: [getOperationName(FIND_MANY_OBJECT_METADATA_ITEMS) ?? ''],
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
createOneRelationMetadataItem,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,39 @@
|
||||
import { ApolloClient, useMutation } from '@apollo/client';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
|
||||
import {
|
||||
DeleteOneFieldMetadataItemMutation,
|
||||
DeleteOneFieldMetadataItemMutationVariables,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { DELETE_ONE_FIELD_METADATA_ITEM } from '../graphql/mutations';
|
||||
import { FIND_MANY_OBJECT_METADATA_ITEMS } from '../graphql/queries';
|
||||
|
||||
import { useApolloMetadataClient } from './useApolloMetadataClient';
|
||||
|
||||
export const useDeleteOneFieldMetadataItem = () => {
|
||||
const apolloMetadataClient = useApolloMetadataClient();
|
||||
|
||||
const [mutate] = useMutation<
|
||||
DeleteOneFieldMetadataItemMutation,
|
||||
DeleteOneFieldMetadataItemMutationVariables
|
||||
>(DELETE_ONE_FIELD_METADATA_ITEM, {
|
||||
client: apolloMetadataClient ?? ({} as ApolloClient<any>),
|
||||
});
|
||||
|
||||
const deleteOneFieldMetadataItem = async (
|
||||
idToDelete: DeleteOneFieldMetadataItemMutationVariables['idToDelete'],
|
||||
) => {
|
||||
return await mutate({
|
||||
variables: {
|
||||
idToDelete,
|
||||
},
|
||||
awaitRefetchQueries: true,
|
||||
refetchQueries: [getOperationName(FIND_MANY_OBJECT_METADATA_ITEMS) ?? ''],
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
deleteOneFieldMetadataItem,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,39 @@
|
||||
import { ApolloClient, useMutation } from '@apollo/client';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
|
||||
import {
|
||||
DeleteOneObjectMetadataItemMutation,
|
||||
DeleteOneObjectMetadataItemMutationVariables,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { DELETE_ONE_OBJECT_METADATA_ITEM } from '../graphql/mutations';
|
||||
import { FIND_MANY_OBJECT_METADATA_ITEMS } from '../graphql/queries';
|
||||
|
||||
import { useApolloMetadataClient } from './useApolloMetadataClient';
|
||||
|
||||
export const useDeleteOneObjectMetadataItem = () => {
|
||||
const apolloMetadataClient = useApolloMetadataClient();
|
||||
|
||||
const [mutate] = useMutation<
|
||||
DeleteOneObjectMetadataItemMutation,
|
||||
DeleteOneObjectMetadataItemMutationVariables
|
||||
>(DELETE_ONE_OBJECT_METADATA_ITEM, {
|
||||
client: apolloMetadataClient ?? ({} as ApolloClient<any>),
|
||||
});
|
||||
|
||||
const deleteOneObjectMetadataItem = async (
|
||||
idToDelete: DeleteOneObjectMetadataItemMutationVariables['idToDelete'],
|
||||
) => {
|
||||
return await mutate({
|
||||
variables: {
|
||||
idToDelete,
|
||||
},
|
||||
awaitRefetchQueries: true,
|
||||
refetchQueries: [getOperationName(FIND_MANY_OBJECT_METADATA_ITEMS) ?? ''],
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
deleteOneObjectMetadataItem,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,72 @@
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { FieldType } from '@/object-record/field/types/FieldType';
|
||||
import { Field } from '~/generated/graphql';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
import { FieldMetadataItem } from '../types/FieldMetadataItem';
|
||||
import { FieldMetadataOption } from '../types/FieldMetadataOption';
|
||||
import { formatFieldMetadataItemInput } from '../utils/formatFieldMetadataItemInput';
|
||||
|
||||
import { useCreateOneFieldMetadataItem } from './useCreateOneFieldMetadataItem';
|
||||
import { useDeleteOneFieldMetadataItem } from './useDeleteOneFieldMetadataItem';
|
||||
import { useUpdateOneFieldMetadataItem } from './useUpdateOneFieldMetadataItem';
|
||||
|
||||
export const useFieldMetadataItem = () => {
|
||||
const { createOneFieldMetadataItem } = useCreateOneFieldMetadataItem();
|
||||
const { updateOneFieldMetadataItem } = useUpdateOneFieldMetadataItem();
|
||||
const { deleteOneFieldMetadataItem } = useDeleteOneFieldMetadataItem();
|
||||
|
||||
const createMetadataField = (
|
||||
input: Pick<Field, 'label' | 'icon' | 'description'> & {
|
||||
objectMetadataId: string;
|
||||
options?: Omit<FieldMetadataOption, 'id'>[];
|
||||
type: FieldMetadataType;
|
||||
},
|
||||
) =>
|
||||
createOneFieldMetadataItem({
|
||||
...formatFieldMetadataItemInput(input),
|
||||
objectMetadataId: input.objectMetadataId,
|
||||
type: input.type as FieldType,
|
||||
});
|
||||
|
||||
const editMetadataField = (
|
||||
input: Pick<Field, 'id' | 'label' | 'icon' | 'description'> & {
|
||||
options?: FieldMetadataOption[];
|
||||
},
|
||||
) =>
|
||||
updateOneFieldMetadataItem({
|
||||
fieldMetadataIdToUpdate: input.id,
|
||||
updatePayload: formatFieldMetadataItemInput({
|
||||
...input,
|
||||
// In Edit mode, all options need an id,
|
||||
// so we generate an id for newly created options.
|
||||
options: input.options?.map((option) =>
|
||||
option.id ? option : { ...option, id: v4() },
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
const activateMetadataField = (metadataField: FieldMetadataItem) =>
|
||||
updateOneFieldMetadataItem({
|
||||
fieldMetadataIdToUpdate: metadataField.id,
|
||||
updatePayload: { isActive: true },
|
||||
});
|
||||
|
||||
const disableMetadataField = (metadataField: FieldMetadataItem) =>
|
||||
updateOneFieldMetadataItem({
|
||||
fieldMetadataIdToUpdate: metadataField.id,
|
||||
updatePayload: { isActive: false },
|
||||
});
|
||||
|
||||
const eraseMetadataField = (metadataField: FieldMetadataItem) =>
|
||||
deleteOneFieldMetadataItem(metadataField.id);
|
||||
|
||||
return {
|
||||
activateMetadataField,
|
||||
createMetadataField,
|
||||
disableMetadataField,
|
||||
eraseMetadataField,
|
||||
editMetadataField,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,63 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useQuery } from '@apollo/client';
|
||||
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import {
|
||||
FieldFilter,
|
||||
ObjectFilter,
|
||||
ObjectMetadataItemsQuery,
|
||||
ObjectMetadataItemsQueryVariables,
|
||||
} from '~/generated-metadata/graphql';
|
||||
import { logError } from '~/utils/logError';
|
||||
|
||||
import { FIND_MANY_OBJECT_METADATA_ITEMS } from '../graphql/queries';
|
||||
import { mapPaginatedObjectMetadataItemsToObjectMetadataItems } from '../utils/mapPaginatedObjectMetadataItemsToObjectMetadataItems';
|
||||
|
||||
import { useApolloMetadataClient } from './useApolloMetadataClient';
|
||||
|
||||
export const useFindManyObjectMetadataItems = ({
|
||||
skip,
|
||||
objectFilter,
|
||||
fieldFilter,
|
||||
}: {
|
||||
skip?: boolean;
|
||||
objectFilter?: ObjectFilter;
|
||||
fieldFilter?: FieldFilter;
|
||||
} = {}) => {
|
||||
const apolloMetadataClient = useApolloMetadataClient();
|
||||
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
|
||||
const { data, loading, error } = useQuery<
|
||||
ObjectMetadataItemsQuery,
|
||||
ObjectMetadataItemsQueryVariables
|
||||
>(FIND_MANY_OBJECT_METADATA_ITEMS, {
|
||||
variables: {
|
||||
objectFilter,
|
||||
fieldFilter,
|
||||
},
|
||||
client: apolloMetadataClient ?? undefined,
|
||||
skip: skip || !apolloMetadataClient,
|
||||
onError: (error) => {
|
||||
logError('useFindManyObjectMetadataItems error : ' + error);
|
||||
enqueueSnackBar(
|
||||
`Error during useFindManyObjectMetadataItems, ${error.message}`,
|
||||
{
|
||||
variant: 'error',
|
||||
},
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const objectMetadataItems = useMemo(() => {
|
||||
return mapPaginatedObjectMetadataItemsToObjectMetadataItems({
|
||||
pagedObjectMetadataItems: data,
|
||||
});
|
||||
}, [data]);
|
||||
|
||||
return {
|
||||
objectMetadataItems,
|
||||
loading,
|
||||
error,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,14 @@
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { OrderBy } from '@/object-metadata/types/OrderBy';
|
||||
import { OrderByField } from '@/object-metadata/types/OrderByField';
|
||||
import { getObjectOrderByField } from '@/object-metadata/utils/getObjectOrderByField';
|
||||
|
||||
export const useGetObjectOrderByField = ({
|
||||
objectMetadataItem,
|
||||
}: {
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
}) => {
|
||||
return (orderBy: OrderBy): OrderByField => {
|
||||
return getObjectOrderByField(objectMetadataItem, orderBy);
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,108 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { FieldType } from '@/object-record/field/types/FieldType';
|
||||
|
||||
import { FieldMetadataItem } from '../types/FieldMetadataItem';
|
||||
|
||||
export const useMapFieldMetadataToGraphQLQuery = () => {
|
||||
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
||||
|
||||
const mapFieldMetadataToGraphQLQuery = (
|
||||
field: FieldMetadataItem,
|
||||
maxDepthForRelations: number = 2,
|
||||
): any => {
|
||||
if (maxDepthForRelations <= 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// TODO: parse
|
||||
const fieldType = field.type as FieldType;
|
||||
|
||||
const fieldIsSimpleValue = (
|
||||
[
|
||||
'UUID',
|
||||
'TEXT',
|
||||
'PHONE',
|
||||
'DATE_TIME',
|
||||
'EMAIL',
|
||||
'NUMBER',
|
||||
'BOOLEAN',
|
||||
] as FieldType[]
|
||||
).includes(fieldType);
|
||||
|
||||
if (fieldIsSimpleValue) {
|
||||
return field.name;
|
||||
} else if (
|
||||
fieldType === 'RELATION' &&
|
||||
field.toRelationMetadata?.relationType === 'ONE_TO_MANY'
|
||||
) {
|
||||
const relationMetadataItem = objectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
objectMetadataItem.id ===
|
||||
(field.toRelationMetadata as any)?.fromObjectMetadata?.id,
|
||||
);
|
||||
|
||||
return `${field.name}
|
||||
{
|
||||
id
|
||||
${(relationMetadataItem?.fields ?? [])
|
||||
.filter((field) => field.type !== 'RELATION')
|
||||
.map((field) =>
|
||||
mapFieldMetadataToGraphQLQuery(field, maxDepthForRelations - 1),
|
||||
)
|
||||
.join('\n')}
|
||||
}`;
|
||||
} else if (
|
||||
fieldType === 'RELATION' &&
|
||||
field.fromRelationMetadata?.relationType === 'ONE_TO_MANY'
|
||||
) {
|
||||
const relationMetadataItem = objectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
objectMetadataItem.id ===
|
||||
(field.fromRelationMetadata as any)?.toObjectMetadata?.id,
|
||||
);
|
||||
|
||||
return `${field.name}
|
||||
{
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
${(relationMetadataItem?.fields ?? [])
|
||||
.filter((field) => field.type !== 'RELATION')
|
||||
.map((field) =>
|
||||
mapFieldMetadataToGraphQLQuery(field, maxDepthForRelations - 1),
|
||||
)
|
||||
.join('\n')}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
} else if (fieldType === 'LINK') {
|
||||
return `
|
||||
${field.name}
|
||||
{
|
||||
label
|
||||
url
|
||||
}
|
||||
`;
|
||||
} else if (fieldType === 'CURRENCY') {
|
||||
return `
|
||||
${field.name}
|
||||
{
|
||||
amountMicros
|
||||
currencyCode
|
||||
}
|
||||
`;
|
||||
} else if (fieldType === 'FULL_NAME') {
|
||||
return `
|
||||
${field.name}
|
||||
{
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
`;
|
||||
}
|
||||
};
|
||||
|
||||
return mapFieldMetadataToGraphQLQuery;
|
||||
};
|
||||
@ -0,0 +1,69 @@
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { ObjectRecordIdentifier } from '@/object-record/types/ObjectRecordIdentifier';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { getLogoUrlFromDomainName } from '~/utils';
|
||||
|
||||
export const useMapToObjectRecordIdentifier = ({
|
||||
objectMetadataItem,
|
||||
}: {
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
}) => {
|
||||
return (record: any): ObjectRecordIdentifier => {
|
||||
switch (objectMetadataItem.nameSingular) {
|
||||
case CoreObjectNameSingular.Opportunity:
|
||||
return {
|
||||
id: record.id,
|
||||
name: record?.company?.name,
|
||||
avatarUrl: record.avatarUrl,
|
||||
avatarType: 'rounded',
|
||||
};
|
||||
}
|
||||
|
||||
const labelIdentifierFieldMetadata = objectMetadataItem.fields.find(
|
||||
(field) =>
|
||||
field.id === objectMetadataItem.labelIdentifierFieldMetadataId ||
|
||||
field.name === 'name',
|
||||
);
|
||||
|
||||
let labelIdentifierFieldValue = '';
|
||||
|
||||
switch (labelIdentifierFieldMetadata?.type) {
|
||||
case FieldMetadataType.FullName: {
|
||||
labelIdentifierFieldValue = `${record.name?.firstName ?? ''} ${
|
||||
record.name?.lastName ?? ''
|
||||
}`;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
labelIdentifierFieldValue = labelIdentifierFieldMetadata
|
||||
? record[labelIdentifierFieldMetadata.name]
|
||||
: '';
|
||||
}
|
||||
|
||||
const imageIdentifierFieldMetadata = objectMetadataItem.fields.find(
|
||||
(field) => field.id === objectMetadataItem.imageIdentifierFieldMetadataId,
|
||||
);
|
||||
|
||||
const imageIdentifierFieldValue = imageIdentifierFieldMetadata
|
||||
? (record[imageIdentifierFieldMetadata.name] as string)
|
||||
: null;
|
||||
|
||||
const avatarType =
|
||||
objectMetadataItem.nameSingular === CoreObjectNameSingular.Company
|
||||
? 'squared'
|
||||
: 'rounded';
|
||||
|
||||
const avatarUrl =
|
||||
objectMetadataItem.nameSingular === CoreObjectNameSingular.Company
|
||||
? getLogoUrlFromDomainName(imageIdentifierFieldValue ?? '')
|
||||
: imageIdentifierFieldValue ?? null;
|
||||
|
||||
return {
|
||||
id: record.id,
|
||||
name: labelIdentifierFieldValue,
|
||||
avatarUrl,
|
||||
avatarType,
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,130 @@
|
||||
import { gql } from '@apollo/client';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { ObjectMetadataItemNotFoundError } from '@/object-metadata/errors/ObjectMetadataNotFoundError';
|
||||
import { useGetObjectOrderByField } from '@/object-metadata/hooks/useGetObjectOrderByField';
|
||||
import { useMapToObjectRecordIdentifier } from '@/object-metadata/hooks/useMapToObjectRecordIdentifier';
|
||||
import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objectMetadataItemFamilySelector';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||
import { useGenerateCreateManyRecordMutation } from '@/object-record/hooks/useGenerateCreateManyRecordMutation';
|
||||
import { useGenerateCreateOneRecordMutation } from '@/object-record/hooks/useGenerateCreateOneRecordMutation';
|
||||
import { useGenerateFindManyRecordsQuery } from '@/object-record/hooks/useGenerateFindManyRecordsQuery';
|
||||
import { useGenerateFindOneRecordQuery } from '@/object-record/hooks/useGenerateFindOneRecordQuery';
|
||||
import { useGenerateUpdateOneRecordMutation } from '@/object-record/hooks/useGenerateUpdateOneRecordMutation';
|
||||
import { useGetRecordFromCache } from '@/object-record/hooks/useGetRecordFromCache';
|
||||
import { useModifyRecordFromCache } from '@/object-record/hooks/useModifyRecordFromCache';
|
||||
import { generateDeleteOneRecordMutation } from '@/object-record/utils/generateDeleteOneRecordMutation';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
import { ObjectMetadataItemIdentifier } from '../types/ObjectMetadataItemIdentifier';
|
||||
|
||||
export const EMPTY_QUERY = gql`
|
||||
query EmptyQuery {
|
||||
empty
|
||||
}
|
||||
`;
|
||||
|
||||
export const EMPTY_MUTATION = gql`
|
||||
mutation EmptyMutation {
|
||||
empty
|
||||
}
|
||||
`;
|
||||
|
||||
export const useObjectMetadataItem = (
|
||||
{ objectNameSingular }: ObjectMetadataItemIdentifier,
|
||||
depth?: number,
|
||||
) => {
|
||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||
const mockObjectMetadataItems = getObjectMetadataItemsMock();
|
||||
|
||||
let objectMetadataItem = useRecoilValue(
|
||||
objectMetadataItemFamilySelector({
|
||||
objectName: objectNameSingular,
|
||||
objectNameType: 'singular',
|
||||
}),
|
||||
);
|
||||
|
||||
let objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
||||
|
||||
if (!currentWorkspace) {
|
||||
objectMetadataItem =
|
||||
mockObjectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
objectMetadataItem.nameSingular === objectNameSingular,
|
||||
) ?? null;
|
||||
objectMetadataItems = mockObjectMetadataItems;
|
||||
}
|
||||
|
||||
if (!isDefined(objectMetadataItem)) {
|
||||
throw new ObjectMetadataItemNotFoundError(
|
||||
objectNameSingular,
|
||||
objectMetadataItems,
|
||||
);
|
||||
}
|
||||
|
||||
const mapToObjectRecordIdentifier = useMapToObjectRecordIdentifier({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
const getObjectOrderByField = useGetObjectOrderByField({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
const getRecordFromCache = useGetRecordFromCache({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
const modifyRecordFromCache = useModifyRecordFromCache({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
const findManyRecordsQuery = useGenerateFindManyRecordsQuery({
|
||||
objectMetadataItem,
|
||||
depth,
|
||||
});
|
||||
|
||||
const findOneRecordQuery = useGenerateFindOneRecordQuery({
|
||||
objectMetadataItem,
|
||||
depth,
|
||||
});
|
||||
|
||||
const createOneRecordMutation = useGenerateCreateOneRecordMutation({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
const createManyRecordsMutation = useGenerateCreateManyRecordMutation({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
const updateOneRecordMutation = useGenerateUpdateOneRecordMutation({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
const deleteOneRecordMutation = generateDeleteOneRecordMutation({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
const labelIdentifierFieldMetadataId = objectMetadataItem.fields.find(
|
||||
({ name }) => name === 'name',
|
||||
)?.id;
|
||||
|
||||
const basePathToShowPage = `/object/${objectMetadataItem.nameSingular}/`;
|
||||
|
||||
return {
|
||||
labelIdentifierFieldMetadataId,
|
||||
basePathToShowPage,
|
||||
objectMetadataItem,
|
||||
getRecordFromCache,
|
||||
modifyRecordFromCache,
|
||||
findManyRecordsQuery,
|
||||
findOneRecordQuery,
|
||||
createOneRecordMutation,
|
||||
updateOneRecordMutation,
|
||||
deleteOneRecordMutation,
|
||||
createManyRecordsMutation,
|
||||
mapToObjectRecordIdentifier,
|
||||
getObjectOrderByField,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,95 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
|
||||
import { ObjectMetadataItem } from '../types/ObjectMetadataItem';
|
||||
import { formatObjectMetadataItemInput } from '../utils/formatObjectMetadataItemInput';
|
||||
import { getObjectSlug } from '../utils/getObjectSlug';
|
||||
|
||||
import { useCreateOneObjectRecordMetadataItem } from './useCreateOneObjectMetadataItem';
|
||||
import { useDeleteOneObjectMetadataItem } from './useDeleteOneObjectMetadataItem';
|
||||
import { useUpdateOneObjectMetadataItem } from './useUpdateOneObjectMetadataItem';
|
||||
|
||||
export const useObjectMetadataItemForSettings = () => {
|
||||
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
||||
|
||||
const activeObjectMetadataItems = objectMetadataItems.filter(
|
||||
({ isActive, isSystem }) => isActive && !isSystem,
|
||||
);
|
||||
const disabledObjectMetadataItems = objectMetadataItems.filter(
|
||||
({ isActive, isSystem }) => !isActive && !isSystem,
|
||||
);
|
||||
|
||||
const findActiveObjectMetadataItemBySlug = (slug: string) =>
|
||||
activeObjectMetadataItems.find(
|
||||
(activeObjectMetadataItem) =>
|
||||
getObjectSlug(activeObjectMetadataItem) === slug,
|
||||
);
|
||||
|
||||
const findObjectMetadataItemById = (id: string) =>
|
||||
objectMetadataItems.find(
|
||||
(objectMetadataItem) => objectMetadataItem.id === id,
|
||||
);
|
||||
|
||||
const findObjectMetadataItemByNamePlural = (namePlural: string) =>
|
||||
objectMetadataItems.find(
|
||||
(objectMetadataItem) => objectMetadataItem.namePlural === namePlural,
|
||||
);
|
||||
|
||||
const { createOneObjectMetadataItem } =
|
||||
useCreateOneObjectRecordMetadataItem();
|
||||
const { updateOneObjectMetadataItem } = useUpdateOneObjectMetadataItem();
|
||||
const { deleteOneObjectMetadataItem } = useDeleteOneObjectMetadataItem();
|
||||
|
||||
const createObjectMetadataItem = (
|
||||
input: Pick<
|
||||
ObjectMetadataItem,
|
||||
'labelPlural' | 'labelSingular' | 'icon' | 'description'
|
||||
>,
|
||||
) => createOneObjectMetadataItem(formatObjectMetadataItemInput(input));
|
||||
|
||||
const editObjectMetadataItem = (
|
||||
input: Pick<
|
||||
ObjectMetadataItem,
|
||||
'id' | 'labelPlural' | 'labelSingular' | 'icon' | 'description'
|
||||
>,
|
||||
) =>
|
||||
updateOneObjectMetadataItem({
|
||||
idToUpdate: input.id,
|
||||
updatePayload: formatObjectMetadataItemInput(input),
|
||||
});
|
||||
|
||||
const activateObjectMetadataItem = (
|
||||
objectMetadataItem: Pick<ObjectMetadataItem, 'id'>,
|
||||
) =>
|
||||
updateOneObjectMetadataItem({
|
||||
idToUpdate: objectMetadataItem.id,
|
||||
updatePayload: { isActive: true },
|
||||
});
|
||||
|
||||
const disableObjectMetadataItem = (
|
||||
objectMetadataItem: Pick<ObjectMetadataItem, 'id'>,
|
||||
) =>
|
||||
updateOneObjectMetadataItem({
|
||||
idToUpdate: objectMetadataItem.id,
|
||||
updatePayload: { isActive: false },
|
||||
});
|
||||
|
||||
const eraseObjectMetadataItem = (
|
||||
objectMetadataItem: Pick<ObjectMetadataItem, 'id'>,
|
||||
) => deleteOneObjectMetadataItem(objectMetadataItem.id);
|
||||
|
||||
return {
|
||||
activateObjectMetadataItem,
|
||||
activeObjectMetadataItems,
|
||||
createObjectMetadataItem,
|
||||
disabledObjectMetadataItems,
|
||||
disableObjectMetadataItem,
|
||||
editObjectMetadataItem,
|
||||
eraseObjectMetadataItem,
|
||||
findActiveObjectMetadataItemBySlug,
|
||||
findObjectMetadataItemById,
|
||||
findObjectMetadataItemByNamePlural,
|
||||
objectMetadataItems,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,38 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objectMetadataItemFamilySelector';
|
||||
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const useObjectNamePluralFromSingular = ({
|
||||
objectNameSingular,
|
||||
}: {
|
||||
objectNameSingular: string;
|
||||
}) => {
|
||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||
const mockObjectMetadataItems = getObjectMetadataItemsMock();
|
||||
|
||||
let objectMetadataItem = useRecoilValue(
|
||||
objectMetadataItemFamilySelector({
|
||||
objectName: objectNameSingular,
|
||||
objectNameType: 'singular',
|
||||
}),
|
||||
);
|
||||
|
||||
if (!currentWorkspace) {
|
||||
objectMetadataItem =
|
||||
mockObjectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
objectMetadataItem.nameSingular === objectNameSingular,
|
||||
) ?? null;
|
||||
}
|
||||
|
||||
if (!isDefined(objectMetadataItem)) {
|
||||
throw new Error(
|
||||
`Object metadata item not found for ${objectNameSingular} object`,
|
||||
);
|
||||
}
|
||||
|
||||
return { objectNamePlural: objectMetadataItem.namePlural };
|
||||
};
|
||||
@ -0,0 +1,38 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objectMetadataItemFamilySelector';
|
||||
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const useObjectNameSingularFromPlural = ({
|
||||
objectNamePlural,
|
||||
}: {
|
||||
objectNamePlural: string;
|
||||
}) => {
|
||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||
const mockObjectMetadataItems = getObjectMetadataItemsMock();
|
||||
|
||||
let objectMetadataItem = useRecoilValue(
|
||||
objectMetadataItemFamilySelector({
|
||||
objectName: objectNamePlural,
|
||||
objectNameType: 'plural',
|
||||
}),
|
||||
);
|
||||
|
||||
if (!currentWorkspace) {
|
||||
objectMetadataItem =
|
||||
mockObjectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
objectMetadataItem.namePlural === objectNamePlural,
|
||||
) ?? null;
|
||||
}
|
||||
|
||||
if (!isDefined(objectMetadataItem)) {
|
||||
throw new Error(
|
||||
`Object metadata item not found for ${objectNamePlural} object`,
|
||||
);
|
||||
}
|
||||
|
||||
return { objectNameSingular: objectMetadataItem.nameSingular };
|
||||
};
|
||||
@ -0,0 +1,49 @@
|
||||
import { RelationType } from '@/settings/data-model/types/RelationType';
|
||||
import { RelationMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
import { useObjectMetadataItemForSettings } from '../hooks/useObjectMetadataItemForSettings';
|
||||
import { FieldMetadataItem } from '../types/FieldMetadataItem';
|
||||
|
||||
export const useRelationMetadata = ({
|
||||
fieldMetadataItem,
|
||||
}: {
|
||||
fieldMetadataItem?: FieldMetadataItem;
|
||||
}) => {
|
||||
const { findObjectMetadataItemById } = useObjectMetadataItemForSettings();
|
||||
|
||||
const relationMetadata =
|
||||
fieldMetadataItem?.fromRelationMetadata ||
|
||||
fieldMetadataItem?.toRelationMetadata;
|
||||
|
||||
const relationType =
|
||||
relationMetadata?.relationType === RelationMetadataType.OneToMany &&
|
||||
fieldMetadataItem?.toRelationMetadata
|
||||
? 'MANY_TO_ONE'
|
||||
: (relationMetadata?.relationType as RelationType | undefined);
|
||||
|
||||
const relationObjectMetadataId =
|
||||
relationMetadata && 'toObjectMetadata' in relationMetadata
|
||||
? relationMetadata.toObjectMetadata.id
|
||||
: relationMetadata?.fromObjectMetadata.id;
|
||||
|
||||
const relationObjectMetadataItem = relationObjectMetadataId
|
||||
? findObjectMetadataItemById(relationObjectMetadataId)
|
||||
: undefined;
|
||||
|
||||
const relationFieldMetadataId =
|
||||
relationMetadata && 'toFieldMetadataId' in relationMetadata
|
||||
? relationMetadata.toFieldMetadataId
|
||||
: relationMetadata?.fromFieldMetadataId;
|
||||
|
||||
const relationFieldMetadataItem = relationFieldMetadataId
|
||||
? relationObjectMetadataItem?.fields?.find(
|
||||
(field) => field.id === relationFieldMetadataId,
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
relationFieldMetadataItem,
|
||||
relationObjectMetadataItem,
|
||||
relationType,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,50 @@
|
||||
import { useMutation } from '@apollo/client';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
|
||||
import {
|
||||
UpdateOneFieldMetadataItemMutation,
|
||||
UpdateOneFieldMetadataItemMutationVariables,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { UPDATE_ONE_FIELD_METADATA_ITEM } from '../graphql/mutations';
|
||||
import { FIND_MANY_OBJECT_METADATA_ITEMS } from '../graphql/queries';
|
||||
|
||||
import { useApolloMetadataClient } from './useApolloMetadataClient';
|
||||
|
||||
export const useUpdateOneFieldMetadataItem = () => {
|
||||
const apolloMetadataClient = useApolloMetadataClient();
|
||||
|
||||
const [mutate] = useMutation<
|
||||
UpdateOneFieldMetadataItemMutation,
|
||||
UpdateOneFieldMetadataItemMutationVariables
|
||||
>(UPDATE_ONE_FIELD_METADATA_ITEM, {
|
||||
client: apolloMetadataClient ?? undefined,
|
||||
});
|
||||
|
||||
const updateOneFieldMetadataItem = async ({
|
||||
fieldMetadataIdToUpdate,
|
||||
updatePayload,
|
||||
}: {
|
||||
fieldMetadataIdToUpdate: UpdateOneFieldMetadataItemMutationVariables['idToUpdate'];
|
||||
updatePayload: Pick<
|
||||
UpdateOneFieldMetadataItemMutationVariables['updatePayload'],
|
||||
'description' | 'icon' | 'isActive' | 'label' | 'name'
|
||||
>;
|
||||
}) => {
|
||||
return await mutate({
|
||||
variables: {
|
||||
idToUpdate: fieldMetadataIdToUpdate,
|
||||
updatePayload: {
|
||||
...updatePayload,
|
||||
label: updatePayload.label ?? undefined,
|
||||
},
|
||||
},
|
||||
awaitRefetchQueries: true,
|
||||
refetchQueries: [getOperationName(FIND_MANY_OBJECT_METADATA_ITEMS) ?? ''],
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
updateOneFieldMetadataItem,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,54 @@
|
||||
import { useMutation } from '@apollo/client';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
|
||||
import {
|
||||
UpdateOneObjectMetadataItemMutation,
|
||||
UpdateOneObjectMetadataItemMutationVariables,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { UPDATE_ONE_OBJECT_METADATA_ITEM } from '../graphql/mutations';
|
||||
import { FIND_MANY_OBJECT_METADATA_ITEMS } from '../graphql/queries';
|
||||
|
||||
import { useApolloMetadataClient } from './useApolloMetadataClient';
|
||||
|
||||
// TODO: Slice the Apollo store synchronously in the update function instead of subscribing, so we can use update after read in the same function call
|
||||
export const useUpdateOneObjectMetadataItem = () => {
|
||||
const apolloClientMetadata = useApolloMetadataClient();
|
||||
|
||||
const [mutate] = useMutation<
|
||||
UpdateOneObjectMetadataItemMutation,
|
||||
UpdateOneObjectMetadataItemMutationVariables
|
||||
>(UPDATE_ONE_OBJECT_METADATA_ITEM, {
|
||||
client: apolloClientMetadata ?? undefined,
|
||||
});
|
||||
|
||||
const updateOneObjectMetadataItem = async ({
|
||||
idToUpdate,
|
||||
updatePayload,
|
||||
}: {
|
||||
idToUpdate: UpdateOneObjectMetadataItemMutationVariables['idToUpdate'];
|
||||
updatePayload: Pick<
|
||||
UpdateOneObjectMetadataItemMutationVariables['updatePayload'],
|
||||
| 'description'
|
||||
| 'icon'
|
||||
| 'isActive'
|
||||
| 'labelPlural'
|
||||
| 'labelSingular'
|
||||
| 'namePlural'
|
||||
| 'nameSingular'
|
||||
>;
|
||||
}) => {
|
||||
return await mutate({
|
||||
variables: {
|
||||
idToUpdate,
|
||||
updatePayload,
|
||||
},
|
||||
awaitRefetchQueries: true,
|
||||
refetchQueries: [getOperationName(FIND_MANY_OBJECT_METADATA_ITEMS) ?? ''],
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
updateOneObjectMetadataItem,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user