import { CustomField, CustomFieldFromYAML, CustomFieldInput, } from '@atlassian/forge-graphql-types'; import { hasValue, isCustomFieldValueEqual, } from '../../../helpers/isCustomFieldValueEqual'; import { buildCustomFieldToUpdateFormat, isCustomFieldYamlSelectField, mappedCustomFieldsToYamlFormat, } from './buildCustomFields'; /** * Determines whether a custom field needs an update based on the YAML configuration and the current component state. * * @param yamlCustomField - The custom field configuration from YAML * @param componentCustomFields - The custom fields of the current component * @returns boolean - True if the custom field needs an update, false otherwise */ export function doesCustomFieldNeedUpdate( yamlCustomField: CustomFieldFromYAML, componentCustomFields: CustomField[], ): boolean { const componentCustomField = componentCustomFields.find( (currComponentCustomField) => currComponentCustomField.definition.name === yamlCustomField.name, ); // If field not found in component, no update needed if (!componentCustomField) { return false; } const yamlCustomFieldType = yamlCustomField.type.toLowerCase(); const componentCustomFieldToYAML = mappedCustomFieldsToYamlFormat(componentCustomField); const isCustomFieldMatch = componentCustomField.definition.name === yamlCustomField.name && componentCustomFieldToYAML.type === yamlCustomFieldType; if (!isCustomFieldMatch) { return false; } const isValueNotEqual = !isCustomFieldValueEqual( componentCustomFieldToYAML.value, yamlCustomField.value, ); // For single and multi select fields, check if mismatch exists for value(optionId) first, then for display value. if (isCustomFieldYamlSelectField(yamlCustomFieldType)) { // Update if the optionId is not equal and short circuit display value check. if (hasValue(yamlCustomField.value)) { return isValueNotEqual; } // Fallback to display value check if optionId is not present. return !isCustomFieldValueEqual( componentCustomFieldToYAML.displayValue, yamlCustomField.displayValue, ); } return isValueNotEqual; } /** * Filters and builds custom fields that need to be updated. * * @param customFields - The custom fields from YAML configuration * @param currentComponentCustomFields - The custom fields of the current component * @returns CustomFieldInput[] - Array of custom fields that need to be updated */ export function getCustomFieldsForUpdate( customFields: CustomFieldFromYAML[], currentComponentCustomFields: CustomField[], ): CustomFieldInput[] { if (!customFields) { return []; } const updatedCustomFields = customFields.filter((yamlCustomField) => doesCustomFieldNeedUpdate(yamlCustomField, currentComponentCustomFields), ); return buildCustomFieldToUpdateFormat( updatedCustomFields, currentComponentCustomFields, ); }