
META-INF.resources.js.components.ObjectField.ObjectFieldFormBase.tsx Maven / Gradle / Ivy
The newest version!
/**
* SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
* SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
*/
import ClayButton, {ClayButtonWithIcon} from '@clayui/button';
import {Option, Text} from '@clayui/core';
import ClayForm from '@clayui/form';
import {
API,
FormError,
Input,
SingleSelect,
Toggle,
} from '@liferay/object-js-components-web';
import {createResourceURL} from 'frontend-js-web';
import React, {
ChangeEventHandler,
ReactNode,
useEffect,
useMemo,
useState,
} from 'react';
import {defaultLanguageId} from '../../utils/constants';
import {
getDefaultValueFieldSettings,
getUpdatedDefaultValueType,
} from '../../utils/defaultValues';
import {removeFieldSettings} from '../../utils/fieldSettings';
import {toCamelCase} from '../../utils/string';
import {AggregationFormBase} from './AggregationFormBase';
import {AttachmentFormBase} from './AttachmentFormBase';
import {AutoIncrementFormBase} from './AutoIncrementFormBase';
import {TimeStorage} from './TimeStorage';
import {UniqueValues} from './UniqueValues';
import {FORMULA_OUTPUT_OPTIONS, FormulaOutput} from './formulaFieldUtil';
import './ObjectFieldFormBase.scss';
import ClayIcon from '@clayui/icon';
import ClayLoadingIndicator from '@clayui/loading-indicator';
import classNames from 'classnames';
interface ObjectFieldFormBaseProps {
baseResourceURL: string;
children?: ReactNode;
className?: string;
creationLanguageId2?: Liferay.Language.Locale;
dbObjectFieldRequired?: boolean;
disabled?: boolean;
editingObjectField?: boolean;
errors: ObjectFieldErrors;
handleChange: ChangeEventHandler;
modelBuilder?: boolean;
objectDefinition?: ObjectDefinition;
objectField: Partial;
objectFieldBusinessTypesInfo: ObjectFieldBusinessType[];
objectRelationshipId?: number;
onAggregationFilterChange?: (aggregationFilterArray: []) => void;
onObjectRelationshipChange?: (
objectDefinitionExternalReferenceCode2: string
) => void;
onSubmit?: (values?: Partial) => void;
setDbObjectFieldRequired?: (value: boolean) => void;
setValues: (values: Partial) => void;
}
type TObjectRelationship = {
deletionType: string;
edge: boolean;
id: number;
label: LocalizedValue;
name: string;
objectDefinitionExternalReferenceCode2: number;
};
export type ObjectFieldErrors = FormError<
ObjectField & {[key in ObjectFieldSettingName]: unknown}
>;
const fieldSettingsMap = new Map([
[
'Aggregation',
[
{
name: 'filters',
objectFieldId: 0,
value: Array(0),
},
],
],
[
'Attachment',
[
{
name: 'acceptedFileExtensions',
value: 'jpeg, jpg, pdf, png',
},
{
name: 'maximumFileSize',
value: 0,
},
],
],
[
'LongText' || 'Text',
[
{
name: 'showCounter',
value: false,
},
],
],
[
'DateTime',
[
{
name: 'timeStorage',
value: 'convertToUTC',
},
],
],
]);
async function updateListTypeDefinitions(
setListTypeDefinitions: (value: ListTypeDefinition[]) => void
) {
const listTypeDefinitions = await API.getListTypeDefinitions();
setListTypeDefinitions(listTypeDefinitions);
}
async function getObjectFieldSettingsByBusinessType(
objectRelationshipId: number,
setListTypeDefinitions: (value: ListTypeDefinition[]) => void,
setOneToManyObjectRelationship: (value: TObjectRelationship) => void,
setReloadPicklistSingleSelect: (value: boolean) => void,
setSelectedOutputValue: (value: string) => void,
values: Partial
) {
const {businessType, objectFieldSettings} = values;
if (businessType === 'Picklist' || businessType === 'MultiselectPicklist') {
setReloadPicklistSingleSelect(true);
updateListTypeDefinitions(setListTypeDefinitions);
}
if (businessType === 'Formula') {
const output = objectFieldSettings?.find(
(fieldSetting) => fieldSetting.name === 'output'
);
if (output) {
setSelectedOutputValue(
FORMULA_OUTPUT_OPTIONS.find(
(formulaOption) => formulaOption.value === output?.value
)?.value as string
);
}
}
if (businessType === 'Relationship' && objectRelationshipId !== 0) {
const relationshipData =
await API.getObjectRelationship(
objectRelationshipId!
);
if (relationshipData.id) {
setOneToManyObjectRelationship(relationshipData);
}
}
}
export default function ObjectFieldFormBase({
baseResourceURL,
children,
className,
creationLanguageId2,
dbObjectFieldRequired,
disabled,
editingObjectField = false,
errors,
handleChange,
modelBuilder = false,
objectDefinition,
objectField: values,
objectFieldBusinessTypesInfo,
objectRelationshipId,
onAggregationFilterChange,
onObjectRelationshipChange,
onSubmit,
setDbObjectFieldRequired,
setValues,
}: ObjectFieldFormBaseProps) {
const [listTypeDefinitions, setListTypeDefinitions] = useState<
Partial[]
>([]);
const [listTypeDefinitionsURL, setListTypeDefinitionsURL] =
useState('');
const [oneToManyObjectRelationship, setOneToManyObjectRelationship] =
useState();
const [reloadPicklistSingleSelect, setReloadPicklistSingleSelect] =
useState(false);
const [selectedOutputValue, setSelectedOutputValue] = useState();
const validListTypeDefinitionId =
values.listTypeDefinitionId !== undefined &&
values.listTypeDefinitionId !== 0;
const listTypeDefinitionsItems = useMemo(() => {
return listTypeDefinitions.map(({externalReferenceCode, name}) => ({
label: name,
value: externalReferenceCode,
})) as LabelValueObject[];
}, [listTypeDefinitions]);
const selectedListTypeDefinitionExternalReferenceCode = useMemo(() => {
return listTypeDefinitions.find(
({externalReferenceCode}) =>
values.listTypeDefinitionExternalReferenceCode ===
externalReferenceCode
)?.externalReferenceCode;
}, [listTypeDefinitions, values.listTypeDefinitionExternalReferenceCode]);
const handleTypeChange = async (selectedBusinessType: string) => {
const selectedObjectFieldBusinessTypeInfo =
objectFieldBusinessTypesInfo.find(
(objectFieldBusinessTypeInfo) =>
objectFieldBusinessTypeInfo.businessType ===
selectedBusinessType
);
const objectFieldSettings: ObjectFieldSetting[] =
fieldSettingsMap.get(selectedBusinessType) || [];
const indexed =
selectedBusinessType !== 'Aggregation' &&
selectedBusinessType !== 'Formula' &&
selectedBusinessType !== 'Encrypted';
const isSearchableByText =
selectedBusinessType === 'Attachment' ||
selectedObjectFieldBusinessTypeInfo?.dbType === 'Clob' ||
selectedObjectFieldBusinessTypeInfo?.dbType === 'String';
const indexedAsKeyword = isSearchableByText && values.indexedAsKeyword;
const indexedLanguageId =
isSearchableByText && !values.indexedAsKeyword
? values.indexedLanguageId ?? defaultLanguageId
: '';
setSelectedOutputValue(undefined);
setValues({
DBType: selectedObjectFieldBusinessTypeInfo?.dbType,
businessType: selectedObjectFieldBusinessTypeInfo?.businessType,
indexed,
indexedAsKeyword,
indexedLanguageId,
listTypeDefinitionExternalReferenceCode: '',
listTypeDefinitionId: 0,
objectFieldSettings,
state: false,
});
if (onSubmit) {
onSubmit({
...values,
DBType: selectedObjectFieldBusinessTypeInfo?.dbType,
businessType: selectedObjectFieldBusinessTypeInfo?.businessType,
indexed,
indexedAsKeyword,
indexedLanguageId,
listTypeDefinitionExternalReferenceCode: '',
listTypeDefinitionId: 0,
objectFieldSettings,
state: false,
});
}
};
const getMandatoryToggleDisabledState = () => {
if (
objectDefinition?.accountEntryRestricted &&
objectDefinition?.accountEntryRestrictedObjectFieldName ===
values.name
) {
return true;
}
if (values.readOnly === 'true' || values.readOnly === 'conditional') {
return true;
}
if (
oneToManyObjectRelationship &&
oneToManyObjectRelationship.deletionType !== 'disassociate'
) {
return Liferay.FeatureFlags['LPD-34594']
? oneToManyObjectRelationship.edge
: false;
}
if (
!dbObjectFieldRequired &&
editingObjectField &&
objectDefinition?.status?.label === 'approved'
) {
return true;
}
return (
!!values.relationshipType ||
(!Liferay.FeatureFlags['LPD-32050'] && values.localized) ||
values.state
);
};
const handleStateToggleChange = (toggled: boolean) => {
let defaultValue;
let defaultValueType;
if (values.id) {
const currentDefaultValueSettings =
getDefaultValueFieldSettings(values);
defaultValue = currentDefaultValueSettings.defaultValue;
defaultValueType = currentDefaultValueSettings.defaultValueType;
}
if (toggled) {
if (defaultValueType && defaultValue) {
setValues({required: toggled, state: toggled});
if (onSubmit) {
onSubmit({
...values,
required: toggled,
state: toggled,
});
}
}
else if (!defaultValueType || !defaultValue) {
setValues({
objectFieldSettings: getUpdatedDefaultValueType(
values,
'inputAsValue'
),
required: toggled,
state: toggled,
});
if (onSubmit) {
onSubmit({
...values,
objectFieldSettings: getUpdatedDefaultValueType(
values,
'inputAsValue'
),
required: toggled,
state: toggled,
});
}
}
}
else {
setValues({
required: toggled,
state: toggled,
});
if (onSubmit) {
onSubmit({
...values,
required: toggled,
state: toggled,
});
}
}
};
useEffect(() => {
const makeFetch = async () => {
await getObjectFieldSettingsByBusinessType(
objectRelationshipId as number,
setListTypeDefinitions,
setOneToManyObjectRelationship,
setReloadPicklistSingleSelect,
setSelectedOutputValue,
values
);
const listTypeDefinitionsURL = createResourceURL(baseResourceURL, {
p_p_resource_id:
'/object_definitions/get_view_list_type_definitions_url',
}).href;
const {url} = await API.fetchJSON<{
url: string;
}>(listTypeDefinitionsURL);
setListTypeDefinitionsURL(url);
};
makeFetch();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [objectRelationshipId, values.businessType]);
useEffect(() => {
if (reloadPicklistSingleSelect) {
setTimeout(() => setReloadPicklistSingleSelect(false), 200);
}
}, [reloadPicklistSingleSelect]);
return (
<>
{
event.stopPropagation();
if (onSubmit) {
onSubmit();
}
}}
onChange={handleChange}
required
value={
values.name ??
toCamelCase(values.label?.[defaultLanguageId] ?? '', true)
}
/>
className={className}
disabled={disabled}
error={errors.businessType}
items={objectFieldBusinessTypesInfo}
label={Liferay.Language.get('type')}
onSelectionChange={(value) => {
handleTypeChange(value as string);
}}
required
selectedKey={values.businessType}
>
{(item) => (
)}
{values.businessType === 'Attachment' && objectDefinition && (
)}
{values.businessType === 'AutoIncrement' && !editingObjectField && (
)}
{values.businessType === 'Aggregation' &&
objectDefinition?.externalReferenceCode && (
)}
{values.businessType === 'Formula' && (
error={errors.output}
items={FORMULA_OUTPUT_OPTIONS}
label={Liferay.Language.get('output')}
onSelectionChange={(value) => {
let newObjectFieldSettings: ObjectFieldSetting[] = [];
if (values.objectFieldSettings) {
newObjectFieldSettings =
values.objectFieldSettings?.filter(
(objectFieldSetting) =>
objectFieldSetting.name !== 'output'
) as ObjectFieldSetting[];
}
setValues({
objectFieldSettings: [
...newObjectFieldSettings,
{
name: 'output',
value,
},
],
});
if (onSubmit) {
onSubmit({
...values,
objectFieldSettings: [
...newObjectFieldSettings,
{
name: 'output',
value,
},
],
});
}
setSelectedOutputValue(
FORMULA_OUTPUT_OPTIONS.find(
(formulaFieldOption) =>
formulaFieldOption.value === value
)?.value as string
);
}}
required
selectedKey={selectedOutputValue}
/>
)}
{(values.businessType === 'Picklist' ||
values.businessType === 'MultiselectPicklist') && (
{reloadPicklistSingleSelect ? (
) : (
{
const selectedListTypeDefinition =
listTypeDefinitions.find(
({externalReferenceCode}) =>
externalReferenceCode === value
);
if (selectedListTypeDefinition) {
setValues({
listTypeDefinitionExternalReferenceCode:
selectedListTypeDefinition.externalReferenceCode,
listTypeDefinitionId:
selectedListTypeDefinition.id,
objectFieldSettings:
removeFieldSettings(
[
'defaultValue',
'stateFlow',
],
values
),
});
if (onSubmit) {
onSubmit({
...values,
listTypeDefinitionExternalReferenceCode:
selectedListTypeDefinition.externalReferenceCode,
listTypeDefinitionId:
selectedListTypeDefinition.id,
objectFieldSettings:
removeFieldSettings(
[
'defaultValue',
'stateFlow',
],
values
),
});
}
}
}}
selectedKey={
selectedListTypeDefinitionExternalReferenceCode
}
/>
updateListTypeDefinitions(
setListTypeDefinitions
)
}
symbol="reload"
title={Liferay.Language.get('refresh-list')}
/>
)}
{
window.open(listTypeDefinitionsURL, '_blank');
}}
>
{Liferay.Language.get('manage-picklists')}
)}
{values.businessType === 'DateTime' && (
)}
{children}
{values.businessType !== 'Aggregation' &&
values.businessType !== 'AutoIncrement' &&
values.businessType !== 'Formula' && (
{
setValues({required});
if (
dbObjectFieldRequired &&
editingObjectField &&
modelBuilder &&
objectDefinition?.status?.label ===
'approved' &&
setDbObjectFieldRequired
) {
setDbObjectFieldRequired(required);
}
if (onSubmit) {
onSubmit({
...values,
required,
});
}
}}
toggled={values.required || values.state}
/>
)}
{values.businessType === 'Picklist' &&
validListTypeDefinitionId && (
{
handleStateToggleChange(state);
}}
toggled={values.state}
/>
)}
{(values.businessType === 'Text' ||
values.businessType === 'Integer') && (
)}
>
);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy