feat: Revamp navigation bar (#6031)
closes: #4428 Testing for fetchMoreRecords is pending, along with component tests --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
@ -1,21 +1,24 @@
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { isAggregationEnabled } from '@/object-metadata/utils/isAggregationEnabled';
|
||||
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||
import { RecordGqlOperationGqlRecordFields } from '@/object-record/graphql/types/RecordGqlOperationGqlRecordFields';
|
||||
import { capitalize } from '~/utils/string/capitalize';
|
||||
|
||||
export type QueryCursorDirection = 'before' | 'after';
|
||||
|
||||
export const generateFindManyRecordsQuery = ({
|
||||
objectMetadataItem,
|
||||
objectMetadataItems,
|
||||
recordGqlFields,
|
||||
computeReferences,
|
||||
cursorDirection,
|
||||
}: {
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
objectMetadataItems: ObjectMetadataItem[];
|
||||
recordGqlFields?: RecordGqlOperationGqlRecordFields;
|
||||
computeReferences?: boolean;
|
||||
cursorDirection?: QueryCursorDirection;
|
||||
}) => gql`
|
||||
query FindMany${capitalize(
|
||||
objectMetadataItem.namePlural,
|
||||
@ -24,9 +27,11 @@ query FindMany${capitalize(
|
||||
)}FilterInput, $orderBy: [${capitalize(
|
||||
objectMetadataItem.nameSingular,
|
||||
)}OrderByInput], $lastCursor: String, $limit: Int) {
|
||||
${
|
||||
objectMetadataItem.namePlural
|
||||
}(filter: $filter, orderBy: $orderBy, first: $limit, after: $lastCursor){
|
||||
${objectMetadataItem.namePlural}(filter: $filter, orderBy: $orderBy, ${
|
||||
cursorDirection === 'before'
|
||||
? 'last: $limit, before: $lastCursor'
|
||||
: 'first: $limit, after: $lastCursor'
|
||||
} ){
|
||||
edges {
|
||||
node ${mapObjectMetadataToGraphQLQuery({
|
||||
objectMetadataItems,
|
||||
@ -37,11 +42,12 @@ query FindMany${capitalize(
|
||||
cursor
|
||||
}
|
||||
pageInfo {
|
||||
${isAggregationEnabled(objectMetadataItem) ? 'hasNextPage' : ''}
|
||||
hasNextPage
|
||||
hasPreviousPage
|
||||
startCursor
|
||||
endCursor
|
||||
}
|
||||
${isAggregationEnabled(objectMetadataItem) ? 'totalCount' : ''}
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@ -5,7 +5,12 @@ export const getQueryIdentifier = ({
|
||||
filter,
|
||||
orderBy,
|
||||
limit,
|
||||
cursorFilter,
|
||||
}: RecordGqlOperationVariables & {
|
||||
objectNameSingular: string;
|
||||
}) =>
|
||||
objectNameSingular + JSON.stringify(filter) + JSON.stringify(orderBy) + limit;
|
||||
objectNameSingular +
|
||||
JSON.stringify(filter) +
|
||||
JSON.stringify(orderBy) +
|
||||
limit +
|
||||
(cursorFilter ? JSON.stringify(cursorFilter) : undefined);
|
||||
|
||||
@ -1,116 +0,0 @@
|
||||
import { ChipGeneratorPerObjectPerField } from '@/object-metadata/context/PreComputedChipGeneratorsContext';
|
||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { getAvatarType } from '@/object-metadata/utils/getAvatarType';
|
||||
import { getAvatarUrl } from '@/object-metadata/utils/getAvatarUrl';
|
||||
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
|
||||
import { getLabelIdentifierFieldValue } from '@/object-metadata/utils/getLabelIdentifierFieldValue';
|
||||
import { getLinkToShowPage } from '@/object-metadata/utils/getLinkToShowPage';
|
||||
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
||||
import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName';
|
||||
import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber';
|
||||
import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation';
|
||||
import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText';
|
||||
import { RecordChipData } from '@/object-record/record-field/types/RecordChipData';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const isFieldChipDisplay = (
|
||||
field: Pick<FieldMetadataItem, 'type'>,
|
||||
isLabelIdentifier: boolean,
|
||||
) =>
|
||||
isLabelIdentifier &&
|
||||
(isFieldText(field) || isFieldFullName(field) || isFieldNumber(field));
|
||||
|
||||
export const getRecordChipGeneratorPerObjectPerField = (
|
||||
objectMetadataItems: ObjectMetadataItem[],
|
||||
) => {
|
||||
const recordChipGeneratorPerObjectPerField: ChipGeneratorPerObjectPerField =
|
||||
{};
|
||||
|
||||
for (const objectMetadataItem of objectMetadataItems) {
|
||||
const generatorPerField = Object.fromEntries<
|
||||
(record: ObjectRecord) => RecordChipData
|
||||
>(
|
||||
objectMetadataItem.fields
|
||||
.filter(
|
||||
(fieldMetadataItem) =>
|
||||
isLabelIdentifierField({
|
||||
fieldMetadataItem: fieldMetadataItem,
|
||||
objectMetadataItem,
|
||||
}) ||
|
||||
fieldMetadataItem.type === FieldMetadataType.Relation ||
|
||||
isFieldChipDisplay(
|
||||
fieldMetadataItem,
|
||||
isLabelIdentifierField({
|
||||
fieldMetadataItem: fieldMetadataItem,
|
||||
objectMetadataItem,
|
||||
}),
|
||||
),
|
||||
)
|
||||
.map((fieldMetadataItem) => {
|
||||
const objectNameSingularToFind = isLabelIdentifierField({
|
||||
fieldMetadataItem: fieldMetadataItem,
|
||||
objectMetadataItem: objectMetadataItem,
|
||||
})
|
||||
? objectMetadataItem.nameSingular
|
||||
: isFieldRelation(fieldMetadataItem)
|
||||
? fieldMetadataItem.relationDefinition?.targetObjectMetadata
|
||||
.nameSingular ?? undefined
|
||||
: undefined;
|
||||
|
||||
const objectMetadataItemToUse = objectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
objectMetadataItem.nameSingular === objectNameSingularToFind,
|
||||
);
|
||||
|
||||
if (
|
||||
!isDefined(objectMetadataItemToUse) ||
|
||||
!isDefined(objectNameSingularToFind)
|
||||
) {
|
||||
return ['', () => ({}) as any];
|
||||
}
|
||||
|
||||
const labelIdentifierFieldMetadataItem =
|
||||
getLabelIdentifierFieldMetadataItem(objectMetadataItemToUse);
|
||||
|
||||
const imageIdentifierFieldMetadata =
|
||||
objectMetadataItemToUse.fields.find(
|
||||
(field) =>
|
||||
field.id ===
|
||||
objectMetadataItemToUse.imageIdentifierFieldMetadataId,
|
||||
);
|
||||
|
||||
const avatarType = getAvatarType(objectNameSingularToFind);
|
||||
|
||||
return [
|
||||
fieldMetadataItem.name,
|
||||
(record: ObjectRecord) => ({
|
||||
recordId: record.id,
|
||||
name: getLabelIdentifierFieldValue(
|
||||
record,
|
||||
labelIdentifierFieldMetadataItem,
|
||||
objectMetadataItemToUse.nameSingular,
|
||||
),
|
||||
avatarUrl: getAvatarUrl(
|
||||
objectMetadataItemToUse.nameSingular,
|
||||
record,
|
||||
imageIdentifierFieldMetadata,
|
||||
),
|
||||
avatarType,
|
||||
linkToShowPage: getLinkToShowPage(
|
||||
objectMetadataItemToUse.nameSingular,
|
||||
record,
|
||||
),
|
||||
}),
|
||||
];
|
||||
}),
|
||||
);
|
||||
|
||||
recordChipGeneratorPerObjectPerField[objectMetadataItem.nameSingular] =
|
||||
generatorPerField;
|
||||
}
|
||||
|
||||
return recordChipGeneratorPerObjectPerField;
|
||||
};
|
||||
@ -0,0 +1,120 @@
|
||||
import {
|
||||
ChipGeneratorPerObjectNameSingularPerFieldName,
|
||||
IdentifierChipGeneratorPerObject,
|
||||
} from '@/object-metadata/context/PreComputedChipGeneratorsContext';
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { getAvatarType } from '@/object-metadata/utils/getAvatarType';
|
||||
import { getAvatarUrl } from '@/object-metadata/utils/getAvatarUrl';
|
||||
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
|
||||
import { getLabelIdentifierFieldValue } from '@/object-metadata/utils/getLabelIdentifierFieldValue';
|
||||
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
||||
import { isFieldChipDisplay } from '@/object-record/record-field/meta-types/display/utils/isFieldChipDisplay';
|
||||
import { RecordChipData } from '@/object-record/record-field/types/RecordChipData';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const getRecordChipGenerators = (
|
||||
objectMetadataItems: ObjectMetadataItem[],
|
||||
) => {
|
||||
const chipGeneratorPerObjectPerField: ChipGeneratorPerObjectNameSingularPerFieldName =
|
||||
{};
|
||||
|
||||
const identifierChipGeneratorPerObject: IdentifierChipGeneratorPerObject = {};
|
||||
|
||||
for (const objectMetadataItem of objectMetadataItems) {
|
||||
const labelIdentifierFieldMetadataItem =
|
||||
getLabelIdentifierFieldMetadataItem(objectMetadataItem);
|
||||
|
||||
const generatorPerField = Object.fromEntries<
|
||||
(record: ObjectRecord) => RecordChipData
|
||||
>(
|
||||
objectMetadataItem.fields
|
||||
.filter(
|
||||
(fieldMetadataItem) =>
|
||||
labelIdentifierFieldMetadataItem?.id === fieldMetadataItem.id ||
|
||||
fieldMetadataItem.type === FieldMetadataType.Relation ||
|
||||
isFieldChipDisplay(
|
||||
fieldMetadataItem,
|
||||
isLabelIdentifierField({
|
||||
fieldMetadataItem: fieldMetadataItem,
|
||||
objectMetadataItem,
|
||||
}),
|
||||
),
|
||||
)
|
||||
.map((fieldMetadataItem) => {
|
||||
const isLabelIdentifier =
|
||||
labelIdentifierFieldMetadataItem?.id === fieldMetadataItem.id;
|
||||
|
||||
const currentObjectNameSingular = objectMetadataItem.nameSingular;
|
||||
const fieldRelationObjectNameSingular =
|
||||
fieldMetadataItem.relationDefinition?.targetObjectMetadata
|
||||
.nameSingular ?? undefined;
|
||||
|
||||
const objectNameSingularToFind = isLabelIdentifier
|
||||
? currentObjectNameSingular
|
||||
: fieldRelationObjectNameSingular;
|
||||
|
||||
const objectMetadataItemToUse = objectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
objectMetadataItem.nameSingular === objectNameSingularToFind,
|
||||
);
|
||||
|
||||
if (
|
||||
!isDefined(objectMetadataItemToUse) ||
|
||||
!isDefined(objectNameSingularToFind)
|
||||
) {
|
||||
return ['', () => ({}) as any];
|
||||
}
|
||||
|
||||
const labelIdentifierFieldMetadataItemToUse =
|
||||
getLabelIdentifierFieldMetadataItem(objectMetadataItemToUse);
|
||||
|
||||
const imageIdentifierFieldMetadataToUse =
|
||||
objectMetadataItemToUse.fields.find(
|
||||
(field) =>
|
||||
field.id ===
|
||||
objectMetadataItemToUse.imageIdentifierFieldMetadataId,
|
||||
);
|
||||
|
||||
const avatarType = getAvatarType(objectNameSingularToFind);
|
||||
|
||||
return [
|
||||
fieldMetadataItem.name,
|
||||
(record: ObjectRecord) =>
|
||||
({
|
||||
recordId: record.id,
|
||||
name: getLabelIdentifierFieldValue(
|
||||
record,
|
||||
labelIdentifierFieldMetadataItemToUse,
|
||||
objectMetadataItemToUse.nameSingular,
|
||||
),
|
||||
avatarUrl: getAvatarUrl(
|
||||
objectMetadataItemToUse.nameSingular,
|
||||
record,
|
||||
imageIdentifierFieldMetadataToUse,
|
||||
),
|
||||
avatarType,
|
||||
isLabelIdentifier,
|
||||
objectNameSingular: objectNameSingularToFind,
|
||||
}) satisfies RecordChipData,
|
||||
];
|
||||
}),
|
||||
);
|
||||
|
||||
chipGeneratorPerObjectPerField[objectMetadataItem.nameSingular] =
|
||||
generatorPerField;
|
||||
|
||||
if (isDefined(labelIdentifierFieldMetadataItem)) {
|
||||
identifierChipGeneratorPerObject[objectMetadataItem.nameSingular] =
|
||||
chipGeneratorPerObjectPerField[objectMetadataItem.nameSingular]?.[
|
||||
labelIdentifierFieldMetadataItem.name
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
chipGeneratorPerObjectPerField,
|
||||
identifierChipGeneratorPerObject,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user