Files
klz-cables.com/.pnpm-store/v10/files/c3/bae118c1086a473096b76ae984f1bcc75f873dced13750f7cbb28f61ff355afa8228199c0fd9af4164a32a0d9deff3bfc8ead5e8b214fc7053d3109166382a
Marc Mintel 5397309103
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
fix(products): fix breadcrumbs and product filtering (backport from main)
2026-02-24 16:04:21 +01:00

160 lines
5.4 KiB
Plaintext

import { renderTable } from '@payloadcms/ui/rsc';
import { formatDate } from '@payloadcms/ui/shared';
import { flattenAllFields } from 'payload';
import { createSerializableValue } from './createSerializableValue.js';
import { extractRelationshipDisplayValue } from './extractRelationshipDisplayValue.js';
import { extractValueOrRelationshipID } from './extractValueOrRelationshipID.js';
export const handleGroupBy = async ({
clientCollectionConfig,
clientConfig,
collectionConfig,
collectionSlug,
columns,
customCellProps,
drawerSlug,
enableRowSelections,
fieldPermissions,
query,
req,
select,
trash = false,
user,
viewType,
where: whereWithMergedSearch
}) => {
let Table = null;
let columnState;
const dataByGroup = {};
// NOTE: is there a faster/better way to do this?
const flattenedFields = flattenAllFields({
fields: collectionConfig.fields
});
const groupByFieldPath = query.groupBy.replace(/^-/, '');
const groupByField = flattenedFields.find(f => f.name === groupByFieldPath);
// Set up population for relationships
let populate;
if (groupByField?.type === 'relationship' && groupByField.relationTo) {
const relationTo = Array.isArray(groupByField.relationTo) ? groupByField.relationTo : [groupByField.relationTo];
populate = {};
relationTo.forEach(rel => {
const config = clientConfig.collections.find(c => c.slug === rel);
populate[rel] = {
[config?.admin?.useAsTitle || 'id']: true
};
});
}
const distinct = await req.payload.findDistinct({
collection: collectionSlug,
depth: 1,
field: groupByFieldPath,
limit: query?.limit ? Number(query.limit) : undefined,
locale: req.locale,
overrideAccess: false,
page: query?.page ? Number(query.page) : undefined,
populate,
req,
sort: query?.groupBy,
trash,
where: whereWithMergedSearch
});
const data = {
...distinct,
docs: distinct.values?.map(() => ({})) || [],
values: undefined
};
await Promise.all((distinct.values || []).map(async (distinctValue, i) => {
const potentiallyPopulatedRelationship = distinctValue[groupByFieldPath];
// Extract value or relationship ID for database query
const valueOrRelationshipID = extractValueOrRelationshipID(potentiallyPopulatedRelationship);
const groupData = await req.payload.find({
collection: collectionSlug,
depth: 0,
draft: true,
fallbackLocale: false,
includeLockStatus: true,
limit: query?.queryByGroup?.[valueOrRelationshipID]?.limit ? Number(query.queryByGroup[valueOrRelationshipID].limit) : undefined,
locale: req.locale,
overrideAccess: false,
page: query?.queryByGroup?.[valueOrRelationshipID]?.page ? Number(query.queryByGroup[valueOrRelationshipID].page) : undefined,
req,
// Note: if we wanted to enable table-by-table sorting, we could use this:
// sort: query?.queryByGroup?.[valueOrRelationshipID]?.sort,
select,
sort: query?.sort,
trash,
user,
where: {
...(whereWithMergedSearch || {}),
[groupByFieldPath]: {
equals: valueOrRelationshipID
}
}
});
// Extract heading
let heading;
if (potentiallyPopulatedRelationship === null) {
heading = req.i18n.t('general:noValue');
} else if (groupByField?.type === 'relationship') {
const relationshipConfig = Array.isArray(groupByField.relationTo) ? undefined : clientConfig.collections.find(c => c.slug === groupByField.relationTo);
heading = extractRelationshipDisplayValue(potentiallyPopulatedRelationship, clientConfig, relationshipConfig);
} else if (groupByField?.type === 'date') {
heading = formatDate({
date: String(valueOrRelationshipID),
i18n: req.i18n,
pattern: clientConfig.admin.dateFormat
});
} else if (groupByField?.type === 'checkbox') {
if (valueOrRelationshipID === true) {
heading = req.i18n.t('general:true');
}
if (valueOrRelationshipID === false) {
heading = req.i18n.t('general:false');
}
} else {
heading = String(valueOrRelationshipID);
}
// Create serializable value for client
const serializableValue = createSerializableValue(valueOrRelationshipID);
if (groupData.docs && groupData.docs.length > 0) {
const {
columnState: newColumnState,
Table: NewTable
} = renderTable({
clientCollectionConfig,
collectionConfig,
columns,
customCellProps,
data: groupData,
drawerSlug,
enableRowSelections,
fieldPermissions,
groupByFieldPath,
groupByValue: serializableValue,
heading: heading || req.i18n.t('general:noValue'),
i18n: req.i18n,
key: `table-${serializableValue}`,
orderableFieldName: collectionConfig.orderable === true ? '_order' : undefined,
payload: req.payload,
query,
useAsTitle: collectionConfig.admin.useAsTitle,
viewType
});
// Only need to set `columnState` once, using the first table's column state
// This will avoid needing to generate column state explicitly for root context that wraps all tables
if (!columnState) {
columnState = newColumnState;
}
if (!Table) {
Table = [];
}
dataByGroup[serializableValue] = groupData;
Table[i] = NewTable;
}
}));
return {
columnState,
data,
Table
};
};
//# sourceMappingURL=handleGroupBy.js.map