Files
klz-cables.com/.pnpm-store/v10/files/81/168cb012215b635fb42caa9a2cfa05c77eabaf647eea3ad6e3239be5ed9736ff5241fd09dcc77c6cbc41a83c7342507ae8389a037a9bd4311f68c98bc4a99d
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

242 lines
7.2 KiB
Plaintext

import { fieldShouldBeLocalized, groupHasName } from 'payload/shared';
import { fieldHasChanges } from './fieldHasChanges.js';
import { getFieldsForRowComparison } from './getFieldsForRowComparison.js';
/**
* Recursively counts the number of changed fields between comparison and
* version data for a given set of fields.
*/
export function countChangedFields({
config,
fields,
locales,
parentIsLocalized,
valueFrom,
valueTo
}) {
let count = 0;
fields.forEach(field => {
// Don't count the id field since it is not displayed in the UI
if ('name' in field && field.name === 'id') {
return;
}
const fieldType = field.type;
switch (fieldType) {
// Iterable fields are arrays and blocks fields. We iterate over each row and
// count the number of changed fields in each.
case 'array':
case 'blocks':
{
if (locales && fieldShouldBeLocalized({
field,
parentIsLocalized
})) {
locales.forEach(locale => {
const valueFromRows = valueFrom?.[field.name]?.[locale] ?? [];
const valueToRows = valueTo?.[field.name]?.[locale] ?? [];
count += countChangedFieldsInRows({
config,
field,
locales,
parentIsLocalized: parentIsLocalized || field.localized,
valueFromRows,
valueToRows
});
});
} else {
const valueFromRows = valueFrom?.[field.name] ?? [];
const valueToRows = valueTo?.[field.name] ?? [];
count += countChangedFieldsInRows({
config,
field,
locales,
parentIsLocalized: parentIsLocalized || field.localized,
valueFromRows,
valueToRows
});
}
break;
}
// Regular fields without nested fields.
case 'checkbox':
case 'code':
case 'date':
case 'email':
case 'join':
case 'json':
case 'number':
case 'point':
case 'radio':
case 'relationship':
case 'richText':
case 'select':
case 'text':
case 'textarea':
case 'upload':
{
// Fields that have a name and contain data. We can just check if the data has changed.
if (locales && fieldShouldBeLocalized({
field,
parentIsLocalized
})) {
locales.forEach(locale => {
if (fieldHasChanges(valueTo?.[field.name]?.[locale], valueFrom?.[field.name]?.[locale])) {
count++;
}
});
} else if (fieldHasChanges(valueTo?.[field.name], valueFrom?.[field.name])) {
count++;
}
break;
}
// Fields that have nested fields, but don't nest their fields' data.
case 'collapsible':
case 'row':
{
count += countChangedFields({
config,
fields: field.fields,
locales,
parentIsLocalized: parentIsLocalized || field.localized,
valueFrom,
valueTo
});
break;
}
// Fields that have nested fields and nest their fields' data.
case 'group':
{
if (groupHasName(field)) {
if (locales && fieldShouldBeLocalized({
field,
parentIsLocalized
})) {
locales.forEach(locale => {
count += countChangedFields({
config,
fields: field.fields,
locales,
parentIsLocalized: parentIsLocalized || field.localized,
valueFrom: valueFrom?.[field.name]?.[locale],
valueTo: valueTo?.[field.name]?.[locale]
});
});
} else {
count += countChangedFields({
config,
fields: field.fields,
locales,
parentIsLocalized: parentIsLocalized || field.localized,
valueFrom: valueFrom?.[field.name],
valueTo: valueTo?.[field.name]
});
}
} else {
// Unnamed group field: data is NOT nested under `field.name`
count += countChangedFields({
config,
fields: field.fields,
locales,
parentIsLocalized: parentIsLocalized || field.localized,
valueFrom,
valueTo
});
}
break;
}
// Each tab in a tabs field has nested fields. The fields data may be
// nested or not depending on the existence of a name property.
case 'tabs':
{
field.tabs.forEach(tab => {
if ('name' in tab && locales && tab.localized) {
// Named localized tab
locales.forEach(locale => {
count += countChangedFields({
config,
fields: tab.fields,
locales,
parentIsLocalized: parentIsLocalized || tab.localized,
valueFrom: valueFrom?.[tab.name]?.[locale],
valueTo: valueTo?.[tab.name]?.[locale]
});
});
} else if ('name' in tab) {
// Named tab
count += countChangedFields({
config,
fields: tab.fields,
locales,
parentIsLocalized: parentIsLocalized || tab.localized,
valueFrom: valueFrom?.[tab.name],
valueTo: valueTo?.[tab.name]
});
} else {
// Unnamed tab
count += countChangedFields({
config,
fields: tab.fields,
locales,
parentIsLocalized: parentIsLocalized || tab.localized,
valueFrom,
valueTo
});
}
});
break;
}
// UI fields don't have data and are not displayed in the version view
// so we can ignore them.
case 'ui':
{
break;
}
default:
{
const _exhaustiveCheck = fieldType;
throw new Error(`Unexpected field.type in countChangedFields : ${String(fieldType)}`);
}
}
});
return count;
}
export function countChangedFieldsInRows({
config,
field,
locales,
parentIsLocalized,
valueFromRows = [],
valueToRows = []
}) {
let count = 0;
let i = 0;
while (valueFromRows[i] || valueToRows[i]) {
const valueFromRow = valueFromRows?.[i] || {};
const valueToRow = valueToRows?.[i] || {};
const {
fields: rowFields
} = getFieldsForRowComparison({
baseVersionField: {
type: 'text',
fields: [],
path: '',
schemaPath: ''
},
config,
field,
row: i,
valueFromRow,
valueToRow
});
count += countChangedFields({
config,
fields: rowFields,
locales,
parentIsLocalized: parentIsLocalized || field.localized,
valueFrom: valueFromRow,
valueTo: valueToRow
});
i++;
}
return count;
}
//# sourceMappingURL=countChangedFields.js.map