Feat/activities custom objects (#3213)
* WIP * WIP - MultiObjectSearch * WIP * WIP * Finished working version * Fix * Fixed and cleaned * Fix * Disabled files and emails for custom objects * Cleaned console.log * Fixed attachment * Fixed * fix lint --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -5,11 +5,10 @@ import { useOptimisticEffect } from '@/apollo/optimistic-effect/hooks/useOptimis
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { ObjectMetadataItemIdentifier } from '@/object-metadata/types/ObjectMetadataItemIdentifier';
|
||||
import { useGenerateEmptyRecord } from '@/object-record/hooks/useGenerateEmptyRecord';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { capitalize } from '~/utils/string/capitalize';
|
||||
|
||||
export const useCreateManyRecords = <
|
||||
T extends Record<string, unknown> & { id: string },
|
||||
>({
|
||||
export const useCreateManyRecords = <T extends ObjectRecord>({
|
||||
objectNameSingular,
|
||||
}: ObjectMetadataItemIdentifier) => {
|
||||
const { triggerOptimisticEffects } = useOptimisticEffect({
|
||||
@ -27,17 +26,16 @@ export const useCreateManyRecords = <
|
||||
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
const createManyRecords = async (data: Record<string, any>[]) => {
|
||||
const createManyRecords = async (data: Partial<T>[]) => {
|
||||
const withIds = data.map((record) => ({
|
||||
...record,
|
||||
id: (record.id as string) ?? v4(),
|
||||
}));
|
||||
|
||||
withIds.forEach((record) => {
|
||||
const emptyRecord: Record<string, unknown> | undefined =
|
||||
generateEmptyRecord({
|
||||
id: record.id,
|
||||
});
|
||||
const emptyRecord: T | undefined = generateEmptyRecord({
|
||||
id: record.id,
|
||||
} as T);
|
||||
|
||||
if (emptyRecord) {
|
||||
triggerOptimisticEffects({
|
||||
|
||||
@ -34,7 +34,7 @@ export const useCreateOneRecord = <T>({
|
||||
const createOneRecord = async (input: Record<string, any>) => {
|
||||
const recordId = v4();
|
||||
|
||||
const generatedEmptyRecord = generateEmptyRecord<Record<string, unknown>>({
|
||||
const generatedEmptyRecord = generateEmptyRecord({
|
||||
id: recordId,
|
||||
createdAt: new Date().toISOString(),
|
||||
...input,
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { generateEmptyFieldValue } from '@/object-record/utils/generateEmptyFieldValue';
|
||||
|
||||
export const useGenerateEmptyRecord = ({
|
||||
@ -7,11 +8,11 @@ export const useGenerateEmptyRecord = ({
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
}) => {
|
||||
// Todo fix typing once we generate the return base on Metadata
|
||||
const generateEmptyRecord = <T>(input: Partial<T> & { id: string }) => {
|
||||
const generateEmptyRecord = <T extends ObjectRecord>(input: T) => {
|
||||
// Todo replace this by runtime typing
|
||||
const validatedInput = input as { id: string } & { [key: string]: any };
|
||||
const validatedInput = input as T;
|
||||
|
||||
const emptyRecord = {} as Record<string, any>;
|
||||
const emptyRecord = {} as any;
|
||||
|
||||
for (const fieldMetadataItem of objectMetadataItem.fields) {
|
||||
emptyRecord[fieldMetadataItem.name] =
|
||||
@ -19,7 +20,7 @@ export const useGenerateEmptyRecord = ({
|
||||
generateEmptyFieldValue(fieldMetadataItem);
|
||||
}
|
||||
|
||||
return emptyRecord;
|
||||
return emptyRecord as T;
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@ -0,0 +1,84 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { capitalize } from '~/utils/string/capitalize';
|
||||
|
||||
export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({
|
||||
objectMetadataItems,
|
||||
depth,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataItem[];
|
||||
depth?: number;
|
||||
}) => {
|
||||
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
|
||||
|
||||
const capitalizedObjectNameSingulars = objectMetadataItems.map(
|
||||
({ nameSingular }) => capitalize(nameSingular),
|
||||
);
|
||||
|
||||
const filterPerMetadataItemArray = capitalizedObjectNameSingulars
|
||||
.map(
|
||||
(capitalizedObjectNameSingular) =>
|
||||
`$filter${capitalizedObjectNameSingular}: ${capitalizedObjectNameSingular}FilterInput`,
|
||||
)
|
||||
.join(', ');
|
||||
|
||||
const orderByPerMetadataItemArray = capitalizedObjectNameSingulars
|
||||
.map(
|
||||
(capitalizedObjectNameSingular) =>
|
||||
`$orderBy${capitalizedObjectNameSingular}: ${capitalizedObjectNameSingular}OrderByInput`,
|
||||
)
|
||||
.join(', ');
|
||||
|
||||
const lastCursorPerMetadataItemArray = capitalizedObjectNameSingulars
|
||||
.map(
|
||||
(capitalizedObjectNameSingular) =>
|
||||
`$lastCursor${capitalizedObjectNameSingular}: String`,
|
||||
)
|
||||
.join(', ');
|
||||
|
||||
const limitPerMetadataItemArray = capitalizedObjectNameSingulars
|
||||
.map(
|
||||
(capitalizedObjectNameSingular) =>
|
||||
`$limit${capitalizedObjectNameSingular}: Float = 5`,
|
||||
)
|
||||
.join(', ');
|
||||
|
||||
return gql`
|
||||
query FindManyRecordsMultipleMetadataItems(
|
||||
${filterPerMetadataItemArray},
|
||||
${orderByPerMetadataItemArray},
|
||||
${lastCursorPerMetadataItemArray},
|
||||
${limitPerMetadataItemArray}
|
||||
) {
|
||||
${objectMetadataItems
|
||||
.map(
|
||||
({ namePlural, nameSingular, fields }) =>
|
||||
`${namePlural}(filter: $filter${capitalize(
|
||||
nameSingular,
|
||||
)}, orderBy: $orderBy${capitalize(
|
||||
nameSingular,
|
||||
)}, first: $limit${capitalize(
|
||||
nameSingular,
|
||||
)}, after: $lastCursor${capitalize(nameSingular)}){
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
${fields
|
||||
.map((field) => mapFieldMetadataToGraphQLQuery(field, depth))
|
||||
.join('\n')}
|
||||
}
|
||||
cursor
|
||||
}
|
||||
pageInfo {
|
||||
hasNextPage
|
||||
startCursor
|
||||
endCursor
|
||||
}
|
||||
}`,
|
||||
)
|
||||
.join('\n')}
|
||||
}
|
||||
`;
|
||||
};
|
||||
@ -1,7 +1,6 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
||||
import { EMPTY_QUERY } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { capitalize } from '~/utils/string/capitalize';
|
||||
|
||||
@ -14,10 +13,6 @@ export const useGenerateFindManyRecordsQuery = ({
|
||||
}) => {
|
||||
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
|
||||
|
||||
if (!objectMetadataItem) {
|
||||
return EMPTY_QUERY;
|
||||
}
|
||||
|
||||
return gql`
|
||||
query FindMany${capitalize(
|
||||
objectMetadataItem.namePlural,
|
||||
|
||||
@ -67,13 +67,6 @@ export const useRecordTableContextMenuEntries = (
|
||||
|
||||
const { createFavorite, favorites, deleteFavorite } = useFavorites();
|
||||
|
||||
const objectMetadataType =
|
||||
objectNameSingular === 'company'
|
||||
? 'Company'
|
||||
: objectNameSingular === 'person'
|
||||
? 'Person'
|
||||
: 'Custom';
|
||||
|
||||
const handleFavoriteButtonClick = useRecoilCallback(({ snapshot }) => () => {
|
||||
const selectedRowIds = injectSelectorSnapshotValueWithRecordTableScopeId(
|
||||
snapshot,
|
||||
@ -212,14 +205,14 @@ export const useRecordTableContextMenuEntries = (
|
||||
label: 'Task',
|
||||
Icon: IconCheckbox,
|
||||
onClick: () => {
|
||||
openCreateActivityDrawer('Task', objectMetadataType);
|
||||
openCreateActivityDrawer('Task', objectNameSingular);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Note',
|
||||
Icon: IconNotes,
|
||||
onClick: () => {
|
||||
openCreateActivityDrawer('Note', objectMetadataType);
|
||||
openCreateActivityDrawer('Note', objectNameSingular);
|
||||
},
|
||||
},
|
||||
...(dataExecuteQuickActionOnmentEnabled
|
||||
|
||||
Reference in New Issue
Block a user