Fix tasks (#5199)
## Query depth deprecation I'm deprecating depth parameter in our graphql query / cache tooling. They were obsolete since we introduce the possibility to provide RecordGqlFields ## Refactor combinedFindManyRecordHook The hook can now take an array of operationSignatures ## Fix tasks issues Fix optimistic rendering issue. Note that we still haven't handle optimisticEffect on creation properly
This commit is contained in:
@ -4,6 +4,7 @@ import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { useFindManyObjectMetadataItems } from '@/object-metadata/hooks/useFindManyObjectMetadataItems';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
||||
|
||||
@ -19,10 +20,18 @@ export const ObjectMetadataItemsLoadEffect = () => {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDeeplyEqual(objectMetadataItems, newObjectMetadataItems)) {
|
||||
setObjectMetadataItems(newObjectMetadataItems);
|
||||
const toSetObjectMetadataItems = isUndefinedOrNull(currentUser)
|
||||
? getObjectMetadataItemsMock()
|
||||
: newObjectMetadataItems;
|
||||
if (!isDeeplyEqual(objectMetadataItems, toSetObjectMetadataItems)) {
|
||||
setObjectMetadataItems(toSetObjectMetadataItems);
|
||||
}
|
||||
}, [newObjectMetadataItems, objectMetadataItems, setObjectMetadataItems]);
|
||||
}, [
|
||||
currentUser,
|
||||
newObjectMetadataItems,
|
||||
objectMetadataItems,
|
||||
setObjectMetadataItems,
|
||||
]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { ObjectMetadataItemsLoadEffect } from '@/object-metadata/components/ObjectMetadataItemsLoadEffect';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { RelationPickerScope } from '@/object-record/relation-picker/scopes/RelationPickerScope';
|
||||
@ -10,10 +9,8 @@ export const ObjectMetadataItemsProvider = ({
|
||||
children,
|
||||
}: React.PropsWithChildren) => {
|
||||
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||
|
||||
const shouldDisplayChildren =
|
||||
objectMetadataItems.length > 0 || !currentWorkspaceMember;
|
||||
const shouldDisplayChildren = objectMetadataItems.length > 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@ -5,7 +5,7 @@ import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilte
|
||||
import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData';
|
||||
import { PrefetchKey } from '@/prefetch/types/PrefetchKey';
|
||||
import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
|
||||
import { GraphQLView } from '@/views/types/GraphQLView';
|
||||
import { View } from '@/views/types/View';
|
||||
import { getObjectMetadataItemViews } from '@/views/utils/getObjectMetadataItemViews';
|
||||
|
||||
export const ObjectMetadataNavItems = () => {
|
||||
@ -14,9 +14,7 @@ export const ObjectMetadataNavItems = () => {
|
||||
const { getIcon } = useIcons();
|
||||
const currentPath = useLocation().pathname;
|
||||
|
||||
const { records: views } = usePrefetchedData<GraphQLView>(
|
||||
PrefetchKey.AllViews,
|
||||
);
|
||||
const { records: views } = usePrefetchedData<View>(PrefetchKey.AllViews);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { OrderBy } from '@/object-metadata/types/OrderBy';
|
||||
import { OrderByField } from '@/object-metadata/types/OrderByField';
|
||||
import { getOrderByFieldForObjectMetadataItem } from '@/object-metadata/utils/getObjectOrderByField';
|
||||
import { RecordGqlOperationOrderBy } from '@/object-record/graphql/types/RecordGqlOperationOrderBy';
|
||||
|
||||
export const useGetObjectOrderByField = ({
|
||||
objectNameSingular,
|
||||
@ -12,7 +12,9 @@ export const useGetObjectOrderByField = ({
|
||||
objectNameSingular,
|
||||
});
|
||||
|
||||
const getObjectOrderByField = (orderBy: OrderBy): OrderByField => {
|
||||
const getObjectOrderByField = (
|
||||
orderBy: OrderBy,
|
||||
): RecordGqlOperationOrderBy => {
|
||||
return getOrderByFieldForObjectMetadataItem(objectMetadataItem, orderBy);
|
||||
};
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ export const useObjectMetadataItem = ({
|
||||
}: ObjectMetadataItemIdentifier) => {
|
||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||
|
||||
// Todo: deprecate this logic as mocked objectMetadataItems are laod in ObjectMetadataItemsLoadEffect anyway
|
||||
const mockObjectMetadataItems = getObjectMetadataItemsMock();
|
||||
|
||||
let objectMetadataItem = useRecoilValue(
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
import { OrderBy } from '@/object-metadata/types/OrderBy';
|
||||
|
||||
export type OrderByField = {
|
||||
[fieldName: string]: OrderBy | { [subFieldName: string]: OrderBy };
|
||||
};
|
||||
@ -37,21 +37,10 @@ describe('mapFieldMetadataToGraphQLQuery', () => {
|
||||
lastName
|
||||
}`);
|
||||
});
|
||||
it('should not return relation if depth is < 1', async () => {
|
||||
const res = mapFieldMetadataToGraphQLQuery({
|
||||
objectMetadataItems: mockObjectMetadataItems,
|
||||
depth: 0,
|
||||
field: personObjectMetadataItem.fields.find(
|
||||
(field) => field.name === 'company',
|
||||
)!,
|
||||
});
|
||||
expect(formatGQLString(res)).toEqual('');
|
||||
});
|
||||
|
||||
it('should return relation if it matches depth', async () => {
|
||||
it('should return non relation subFields if relation', async () => {
|
||||
const res = mapFieldMetadataToGraphQLQuery({
|
||||
objectMetadataItems: mockObjectMetadataItems,
|
||||
depth: 1,
|
||||
field: personObjectMetadataItem.fields.find(
|
||||
(field) => field.name === 'company',
|
||||
)!,
|
||||
@ -83,168 +72,14 @@ accountOwnerId
|
||||
employees
|
||||
id
|
||||
idealCustomerProfile
|
||||
}`);
|
||||
});
|
||||
it('should return relation with all sub relations if it matches depth', async () => {
|
||||
const res = mapFieldMetadataToGraphQLQuery({
|
||||
objectMetadataItems: mockObjectMetadataItems,
|
||||
depth: 2,
|
||||
field: personObjectMetadataItem.fields.find(
|
||||
(field) => field.name === 'company',
|
||||
)!,
|
||||
});
|
||||
expect(formatGQLString(res)).toEqual(`company
|
||||
{
|
||||
__typename
|
||||
xLink
|
||||
{
|
||||
label
|
||||
url
|
||||
}
|
||||
accountOwner
|
||||
{
|
||||
__typename
|
||||
colorScheme
|
||||
name
|
||||
{
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
locale
|
||||
userId
|
||||
avatarUrl
|
||||
createdAt
|
||||
updatedAt
|
||||
id
|
||||
}
|
||||
linkedinLink
|
||||
{
|
||||
label
|
||||
url
|
||||
}
|
||||
attachments
|
||||
{
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
updatedAt
|
||||
createdAt
|
||||
name
|
||||
personId
|
||||
activityId
|
||||
companyId
|
||||
id
|
||||
authorId
|
||||
type
|
||||
fullPath
|
||||
}
|
||||
}
|
||||
}
|
||||
domainName
|
||||
opportunities
|
||||
{
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
personId
|
||||
pointOfContactId
|
||||
updatedAt
|
||||
companyId
|
||||
probability
|
||||
closeDate
|
||||
amount
|
||||
{
|
||||
amountMicros
|
||||
currencyCode
|
||||
}
|
||||
id
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
annualRecurringRevenue
|
||||
{
|
||||
amountMicros
|
||||
currencyCode
|
||||
}
|
||||
createdAt
|
||||
address
|
||||
updatedAt
|
||||
activityTargets
|
||||
{
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
updatedAt
|
||||
createdAt
|
||||
personId
|
||||
activityId
|
||||
companyId
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
favorites
|
||||
{
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
id
|
||||
companyId
|
||||
createdAt
|
||||
personId
|
||||
position
|
||||
workspaceMemberId
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
people
|
||||
{
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
xLink
|
||||
{
|
||||
label
|
||||
url
|
||||
}
|
||||
id
|
||||
createdAt
|
||||
city
|
||||
email
|
||||
jobTitle
|
||||
name
|
||||
{
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
phone
|
||||
linkedinLink
|
||||
{
|
||||
label
|
||||
url
|
||||
}
|
||||
updatedAt
|
||||
avatarUrl
|
||||
companyId
|
||||
}
|
||||
}
|
||||
}
|
||||
name
|
||||
accountOwnerId
|
||||
employees
|
||||
id
|
||||
idealCustomerProfile
|
||||
}`);
|
||||
});
|
||||
|
||||
it('should return GraphQL fields based on queryFields', async () => {
|
||||
it('should return only return relation subFields that are in recordGqlFields', async () => {
|
||||
const res = mapFieldMetadataToGraphQLQuery({
|
||||
objectMetadataItems: mockObjectMetadataItems,
|
||||
depth: 2,
|
||||
queryFields: {
|
||||
accountOwner: true,
|
||||
relationrecordFields: {
|
||||
accountOwner: { id: true, name: true },
|
||||
people: true,
|
||||
xLink: true,
|
||||
linkedinLink: true,
|
||||
@ -274,17 +109,11 @@ xLink
|
||||
accountOwner
|
||||
{
|
||||
__typename
|
||||
colorScheme
|
||||
name
|
||||
{
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
locale
|
||||
userId
|
||||
avatarUrl
|
||||
createdAt
|
||||
updatedAt
|
||||
id
|
||||
}
|
||||
linkedinLink
|
||||
|
||||
@ -15,209 +15,11 @@ if (!personObjectMetadataItem) {
|
||||
}
|
||||
|
||||
describe('mapObjectMetadataToGraphQLQuery', () => {
|
||||
it('should return typename if depth < 0', async () => {
|
||||
it('should query only specified recordGqlFields', async () => {
|
||||
const res = mapObjectMetadataToGraphQLQuery({
|
||||
objectMetadataItems: mockObjectMetadataItems,
|
||||
objectMetadataItem: personObjectMetadataItem,
|
||||
depth: -1,
|
||||
});
|
||||
expect(formatGQLString(res)).toEqual(`{
|
||||
__typename
|
||||
}`);
|
||||
});
|
||||
|
||||
it('should return depth 0 if depth = 0', async () => {
|
||||
const res = mapObjectMetadataToGraphQLQuery({
|
||||
objectMetadataItems: mockObjectMetadataItems,
|
||||
objectMetadataItem: personObjectMetadataItem,
|
||||
depth: 0,
|
||||
});
|
||||
expect(formatGQLString(res)).toEqual(`{
|
||||
__typename
|
||||
xLink
|
||||
{
|
||||
label
|
||||
url
|
||||
}
|
||||
id
|
||||
createdAt
|
||||
city
|
||||
email
|
||||
jobTitle
|
||||
name
|
||||
{
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
phone
|
||||
linkedinLink
|
||||
{
|
||||
label
|
||||
url
|
||||
}
|
||||
updatedAt
|
||||
avatarUrl
|
||||
companyId
|
||||
}`);
|
||||
});
|
||||
|
||||
it('should return depth 1 if depth = 1', async () => {
|
||||
const res = mapObjectMetadataToGraphQLQuery({
|
||||
objectMetadataItems: mockObjectMetadataItems,
|
||||
objectMetadataItem: personObjectMetadataItem,
|
||||
depth: 1,
|
||||
});
|
||||
expect(formatGQLString(res)).toEqual(`{
|
||||
__typename
|
||||
opportunities
|
||||
{
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
personId
|
||||
pointOfContactId
|
||||
updatedAt
|
||||
companyId
|
||||
probability
|
||||
closeDate
|
||||
amount
|
||||
{
|
||||
amountMicros
|
||||
currencyCode
|
||||
}
|
||||
id
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
xLink
|
||||
{
|
||||
label
|
||||
url
|
||||
}
|
||||
id
|
||||
pointOfContactForOpportunities
|
||||
{
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
personId
|
||||
pointOfContactId
|
||||
updatedAt
|
||||
companyId
|
||||
probability
|
||||
closeDate
|
||||
amount
|
||||
{
|
||||
amountMicros
|
||||
currencyCode
|
||||
}
|
||||
id
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
createdAt
|
||||
company
|
||||
{
|
||||
__typename
|
||||
xLink
|
||||
{
|
||||
label
|
||||
url
|
||||
}
|
||||
linkedinLink
|
||||
{
|
||||
label
|
||||
url
|
||||
}
|
||||
domainName
|
||||
annualRecurringRevenue
|
||||
{
|
||||
amountMicros
|
||||
currencyCode
|
||||
}
|
||||
createdAt
|
||||
address
|
||||
updatedAt
|
||||
name
|
||||
accountOwnerId
|
||||
employees
|
||||
id
|
||||
idealCustomerProfile
|
||||
}
|
||||
city
|
||||
email
|
||||
activityTargets
|
||||
{
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
updatedAt
|
||||
createdAt
|
||||
personId
|
||||
activityId
|
||||
companyId
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
jobTitle
|
||||
favorites
|
||||
{
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
id
|
||||
companyId
|
||||
createdAt
|
||||
personId
|
||||
position
|
||||
workspaceMemberId
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
attachments
|
||||
{
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
updatedAt
|
||||
createdAt
|
||||
name
|
||||
personId
|
||||
activityId
|
||||
companyId
|
||||
id
|
||||
authorId
|
||||
type
|
||||
fullPath
|
||||
}
|
||||
}
|
||||
}
|
||||
name
|
||||
{
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
phone
|
||||
linkedinLink
|
||||
{
|
||||
label
|
||||
url
|
||||
}
|
||||
updatedAt
|
||||
avatarUrl
|
||||
companyId
|
||||
}`);
|
||||
});
|
||||
|
||||
it('should query only specified queryFields', async () => {
|
||||
const res = mapObjectMetadataToGraphQLQuery({
|
||||
objectMetadataItems: mockObjectMetadataItems,
|
||||
objectMetadataItem: personObjectMetadataItem,
|
||||
queryFields: {
|
||||
recordGqlFields: {
|
||||
company: true,
|
||||
xLink: true,
|
||||
id: true,
|
||||
@ -232,7 +34,6 @@ companyId
|
||||
avatarUrl: true,
|
||||
companyId: true,
|
||||
},
|
||||
depth: 1,
|
||||
});
|
||||
expect(formatGQLString(res)).toEqual(`{
|
||||
__typename
|
||||
@ -291,12 +92,11 @@ companyId
|
||||
}`);
|
||||
});
|
||||
|
||||
it('should load only specified query fields', async () => {
|
||||
it('should load only specified operation fields nested', async () => {
|
||||
const res = mapObjectMetadataToGraphQLQuery({
|
||||
objectMetadataItems: mockObjectMetadataItems,
|
||||
objectMetadataItem: personObjectMetadataItem,
|
||||
queryFields: { company: true, id: true, name: true },
|
||||
depth: 1,
|
||||
recordGqlFields: { company: { id: true }, id: true, name: true },
|
||||
});
|
||||
expect(formatGQLString(res)).toEqual(`{
|
||||
__typename
|
||||
@ -304,30 +104,7 @@ id
|
||||
company
|
||||
{
|
||||
__typename
|
||||
xLink
|
||||
{
|
||||
label
|
||||
url
|
||||
}
|
||||
linkedinLink
|
||||
{
|
||||
label
|
||||
url
|
||||
}
|
||||
domainName
|
||||
annualRecurringRevenue
|
||||
{
|
||||
amountMicros
|
||||
currencyCode
|
||||
}
|
||||
createdAt
|
||||
address
|
||||
updatedAt
|
||||
name
|
||||
accountOwnerId
|
||||
employees
|
||||
id
|
||||
idealCustomerProfile
|
||||
}
|
||||
name
|
||||
{
|
||||
|
||||
@ -2,113 +2,50 @@ import { shouldFieldBeQueried } from '@/object-metadata/utils/shouldFieldBeQueri
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
describe('shouldFieldBeQueried', () => {
|
||||
describe('if field is not relation', () => {
|
||||
it('should be queried if depth is undefined', () => {
|
||||
describe('if recordGqlFields is absent, we query all except relations', () => {
|
||||
it('should be queried if the field is not a relation', () => {
|
||||
const res = shouldFieldBeQueried({
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Boolean },
|
||||
});
|
||||
expect(res).toBe(true);
|
||||
});
|
||||
|
||||
it('should be queried depth = 0', () => {
|
||||
it('should not be queried if the field is a relation', () => {
|
||||
const res = shouldFieldBeQueried({
|
||||
depth: 0,
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Boolean },
|
||||
});
|
||||
expect(res).toBe(true);
|
||||
});
|
||||
|
||||
it('should be queried depth > 0', () => {
|
||||
const res = shouldFieldBeQueried({
|
||||
depth: 1,
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Boolean },
|
||||
});
|
||||
expect(res).toBe(true);
|
||||
});
|
||||
|
||||
it('should NOT be queried depth < 0', () => {
|
||||
const res = shouldFieldBeQueried({
|
||||
depth: -1,
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Boolean },
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||
});
|
||||
expect(res).toBe(false);
|
||||
});
|
||||
|
||||
it('should not depends on queryFields', () => {
|
||||
const res = shouldFieldBeQueried({
|
||||
depth: 0,
|
||||
queryFields: {
|
||||
fieldName: true,
|
||||
},
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Boolean },
|
||||
});
|
||||
expect(res).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('if field is relation', () => {
|
||||
it('should be queried if queryFields and depth are undefined', () => {
|
||||
describe('if recordGqlFields is present, we respect it', () => {
|
||||
it('should be queried if true', () => {
|
||||
const res = shouldFieldBeQueried({
|
||||
recordGqlFields: { fieldName: true },
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||
});
|
||||
expect(res).toBe(true);
|
||||
});
|
||||
|
||||
it('should be queried if queryFields is undefined and depth = 1', () => {
|
||||
it('should be queried if object', () => {
|
||||
const res = shouldFieldBeQueried({
|
||||
depth: 1,
|
||||
recordGqlFields: { fieldName: { subFieldName: false } },
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||
});
|
||||
expect(res).toBe(true);
|
||||
});
|
||||
|
||||
it('should be queried if queryFields is undefined and depth > 1', () => {
|
||||
it('should not be queried if false', () => {
|
||||
const res = shouldFieldBeQueried({
|
||||
depth: 2,
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||
});
|
||||
expect(res).toBe(true);
|
||||
});
|
||||
|
||||
it('should NOT be queried if queryFields is undefined and depth < 1', () => {
|
||||
const res = shouldFieldBeQueried({
|
||||
depth: 0,
|
||||
recordGqlFields: { fieldName: false },
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||
});
|
||||
expect(res).toBe(false);
|
||||
});
|
||||
|
||||
it('should be queried if queryFields is matching and depth > 1', () => {
|
||||
it('should not be queried if absent', () => {
|
||||
const res = shouldFieldBeQueried({
|
||||
depth: 1,
|
||||
queryFields: { fieldName: true },
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||
});
|
||||
expect(res).toBe(true);
|
||||
});
|
||||
|
||||
it('should NOT be queried if queryFields is matching and depth < 1', () => {
|
||||
const res = shouldFieldBeQueried({
|
||||
depth: 0,
|
||||
queryFields: { fieldName: true },
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||
});
|
||||
expect(res).toBe(false);
|
||||
});
|
||||
|
||||
it('should NOT be queried if queryFields is not matching (falsy) and depth < 1', () => {
|
||||
const res = shouldFieldBeQueried({
|
||||
depth: 1,
|
||||
queryFields: { fieldName: false },
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||
});
|
||||
expect(res).toBe(false);
|
||||
});
|
||||
|
||||
it('should NOT be queried if queryFields is not matching and depth < 1', () => {
|
||||
const res = shouldFieldBeQueried({
|
||||
depth: 0,
|
||||
queryFields: { anotherFieldName: true },
|
||||
recordGqlFields: { otherFieldName: false },
|
||||
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||
});
|
||||
expect(res).toBe(false);
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { OrderBy } from '@/object-metadata/types/OrderBy';
|
||||
import { OrderByField } from '@/object-metadata/types/OrderByField';
|
||||
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
|
||||
import { RecordGqlOperationOrderBy } from '@/object-record/graphql/types/RecordGqlOperationOrderBy';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const getOrderByFieldForObjectMetadataItem = (
|
||||
objectMetadataItem: ObjectMetadataItem,
|
||||
orderBy?: OrderBy | null,
|
||||
): OrderByField => {
|
||||
): RecordGqlOperationOrderBy => {
|
||||
const labelIdentifierFieldMetadata =
|
||||
getLabelIdentifierFieldMetadataItem(objectMetadataItem);
|
||||
|
||||
|
||||
@ -10,8 +10,7 @@ import { FieldMetadataItem } from '../types/FieldMetadataItem';
|
||||
export const mapFieldMetadataToGraphQLQuery = ({
|
||||
objectMetadataItems,
|
||||
field,
|
||||
depth = 0,
|
||||
queryFields,
|
||||
relationrecordFields,
|
||||
computeReferences = false,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataItem[];
|
||||
@ -19,8 +18,7 @@ export const mapFieldMetadataToGraphQLQuery = ({
|
||||
FieldMetadataItem,
|
||||
'name' | 'type' | 'toRelationMetadata' | 'fromRelationMetadata'
|
||||
>;
|
||||
depth?: number;
|
||||
queryFields?: Record<string, any>;
|
||||
relationrecordFields?: Record<string, any>;
|
||||
computeReferences?: boolean;
|
||||
}): any => {
|
||||
const fieldType = field.type;
|
||||
@ -47,8 +45,7 @@ export const mapFieldMetadataToGraphQLQuery = ({
|
||||
return field.name;
|
||||
} else if (
|
||||
fieldType === 'RELATION' &&
|
||||
field.toRelationMetadata?.relationType === 'ONE_TO_MANY' &&
|
||||
depth > 0
|
||||
field.toRelationMetadata?.relationType === 'ONE_TO_MANY'
|
||||
) {
|
||||
const relationMetadataItem = objectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
@ -64,15 +61,13 @@ export const mapFieldMetadataToGraphQLQuery = ({
|
||||
${mapObjectMetadataToGraphQLQuery({
|
||||
objectMetadataItems,
|
||||
objectMetadataItem: relationMetadataItem,
|
||||
depth: depth - 1,
|
||||
queryFields,
|
||||
recordGqlFields: relationrecordFields,
|
||||
computeReferences: computeReferences,
|
||||
isRootLevel: false,
|
||||
})}`;
|
||||
} else if (
|
||||
fieldType === 'RELATION' &&
|
||||
field.fromRelationMetadata?.relationType === 'ONE_TO_MANY' &&
|
||||
depth > 0
|
||||
field.fromRelationMetadata?.relationType === 'ONE_TO_MANY'
|
||||
) {
|
||||
const relationMetadataItem = objectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
@ -90,8 +85,7 @@ ${mapObjectMetadataToGraphQLQuery({
|
||||
node ${mapObjectMetadataToGraphQLQuery({
|
||||
objectMetadataItems,
|
||||
objectMetadataItem: relationMetadataItem,
|
||||
depth: depth - 1,
|
||||
queryFields,
|
||||
recordGqlFields: relationrecordFields,
|
||||
computeReferences,
|
||||
isRootLevel: false,
|
||||
})}
|
||||
|
||||
@ -5,15 +5,13 @@ import { shouldFieldBeQueried } from '@/object-metadata/utils/shouldFieldBeQueri
|
||||
export const mapObjectMetadataToGraphQLQuery = ({
|
||||
objectMetadataItems,
|
||||
objectMetadataItem,
|
||||
depth = 1,
|
||||
queryFields,
|
||||
recordGqlFields,
|
||||
computeReferences = false,
|
||||
isRootLevel = true,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataItem[];
|
||||
objectMetadataItem: Pick<ObjectMetadataItem, 'nameSingular' | 'fields'>;
|
||||
depth?: number;
|
||||
queryFields?: Record<string, any>;
|
||||
recordGqlFields?: Record<string, any>;
|
||||
computeReferences?: boolean;
|
||||
isRootLevel?: boolean;
|
||||
}): any => {
|
||||
@ -23,8 +21,7 @@ export const mapObjectMetadataToGraphQLQuery = ({
|
||||
.filter((field) =>
|
||||
shouldFieldBeQueried({
|
||||
field,
|
||||
depth,
|
||||
queryFields,
|
||||
recordGqlFields,
|
||||
}),
|
||||
) ?? [];
|
||||
|
||||
@ -37,18 +34,17 @@ export const mapObjectMetadataToGraphQLQuery = ({
|
||||
return `{
|
||||
__typename
|
||||
${fieldsThatShouldBeQueried
|
||||
.map((field) =>
|
||||
mapFieldMetadataToGraphQLQuery({
|
||||
.map((field) => {
|
||||
return mapFieldMetadataToGraphQLQuery({
|
||||
objectMetadataItems,
|
||||
field,
|
||||
depth,
|
||||
queryFields:
|
||||
typeof queryFields?.[field.name] === 'boolean'
|
||||
relationrecordFields:
|
||||
typeof recordGqlFields?.[field.name] === 'boolean'
|
||||
? undefined
|
||||
: queryFields?.[field.name],
|
||||
: recordGqlFields?.[field.name],
|
||||
computeReferences,
|
||||
}),
|
||||
)
|
||||
});
|
||||
})
|
||||
.join('\n')}
|
||||
}`;
|
||||
};
|
||||
|
||||
@ -1,36 +1,32 @@
|
||||
import { isUndefined } from '@sniptt/guards';
|
||||
|
||||
import { RecordGqlOperationGqlRecordFields } from '@/object-record/graphql/types/RecordGqlOperationGqlRecordFields';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
||||
|
||||
import { FieldMetadataItem } from '../types/FieldMetadataItem';
|
||||
|
||||
export const shouldFieldBeQueried = ({
|
||||
field,
|
||||
depth,
|
||||
queryFields,
|
||||
recordGqlFields,
|
||||
}: {
|
||||
field: Pick<FieldMetadataItem, 'name' | 'type'>;
|
||||
depth?: number;
|
||||
objectRecord?: ObjectRecord;
|
||||
queryFields?: Record<string, any>;
|
||||
recordGqlFields?: RecordGqlOperationGqlRecordFields;
|
||||
}): any => {
|
||||
if (!isUndefined(depth) && depth < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!isUndefined(depth) &&
|
||||
depth < 1 &&
|
||||
field.type === FieldMetadataType.Relation
|
||||
isUndefinedOrNull(recordGqlFields) &&
|
||||
field.type !== FieldMetadataType.Relation
|
||||
) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
isDefined(recordGqlFields) &&
|
||||
isDefined(recordGqlFields[field.name]) &&
|
||||
recordGqlFields[field.name] !== false
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isDefined(queryFields) && !queryFields[field.name]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user