diff --git a/packages/components/public/locales/en/boost.json b/packages/components/public/locales/en/boost.json index e326489c..b712842d 100644 --- a/packages/components/public/locales/en/boost.json +++ b/packages/components/public/locales/en/boost.json @@ -22,5 +22,9 @@ "boost_zero": "boost", "boost_one": "boost", "boost_other": "boosts", - "preview": "Preview" + "preview": "Preview", + "boostConfig.sourceField": "Source field", + "boostConfig.sourceField.placeholder": "Select a SourceField", + "boostConfig.boostImpact": "Boost impact", + "boostConfig.scaleFactor": "Scale factor" } diff --git a/packages/components/public/locales/fr/boost.json b/packages/components/public/locales/fr/boost.json index 7f97c01c..5206902f 100644 --- a/packages/components/public/locales/fr/boost.json +++ b/packages/components/public/locales/fr/boost.json @@ -22,5 +22,9 @@ "boost_zero": "boost", "boost_one": "boost", "boost_other": "boosts", - "preview": "Prévisualiser" + "preview": "Prévisualiser", + "boostConfig.sourceField": "Source field", + "boostConfig.sourceField.placeholder": "Sélectionnez un SourceField", + "boostConfig.boostImpact": "Impacte du Boost", + "boostConfig.scaleFactor": "Scale factor" } diff --git a/packages/components/src/components/atoms/form/RadioGroup.tsx b/packages/components/src/components/atoms/form/RadioGroup.tsx index 0a9974f0..127d76e8 100644 --- a/packages/components/src/components/atoms/form/RadioGroup.tsx +++ b/packages/components/src/components/atoms/form/RadioGroup.tsx @@ -12,9 +12,7 @@ import RadioGroupWithoutError, { } from './RadioGroupWithoutError' import InputTextWithoutError from './InputTextWithoutError' -interface IRadioGroupErrorProps extends IFieldErrorProps, IRadioGroupProps { - required?: boolean -} +interface IRadioGroupErrorProps extends IFieldErrorProps, IRadioGroupProps {} function RadioGroup(props: IRadioGroupErrorProps): JSX.Element { const { onChange, showError, additionalValidator, ...inputProps } = props diff --git a/packages/components/src/components/atoms/form/RadioGroupWithoutError.tsx b/packages/components/src/components/atoms/form/RadioGroupWithoutError.tsx index 77c7343b..b3143e94 100644 --- a/packages/components/src/components/atoms/form/RadioGroupWithoutError.tsx +++ b/packages/components/src/components/atoms/form/RadioGroupWithoutError.tsx @@ -1,13 +1,16 @@ import React, { ReactNode, SyntheticEvent } from 'react' import { + FormControl, FormControlLabel, FormHelperText, + InputLabel, Radio, RadioGroupProps, RadioGroup as RadioGrp, } from '@mui/material' import { IOption, IOptions } from '@elastic-suite/gally-admin-shared' import IonIcon from '../IonIcon/IonIcon' +import InfoTooltip from '../../atoms/form/InfoTooltip' export interface IRadioGroupProps extends Omit { options: IOptions @@ -15,6 +18,9 @@ export interface IRadioGroupProps extends Omit { error?: boolean helperText?: ReactNode helperIcon?: string + label?: string + infoTooltip?: string + required?: boolean } function RadioGroupWithoutError(props: IRadioGroupProps): JSX.Element { @@ -24,12 +30,24 @@ function RadioGroupWithoutError(props: IRadioGroupProps): JSX.Element { helperIcon, options, onChange, + infoTooltip, + label, ...radioGroupProps } = props const foundNameDefaultValue = options.find((element) => element.default) return ( -
+ + {Boolean(label || infoTooltip) && ( + + {label} + {infoTooltip ? : null} + + )} { @@ -62,7 +80,7 @@ function RadioGroupWithoutError(props: IRadioGroupProps): JSX.Element { {helperText} )} -
+ ) } diff --git a/packages/components/src/components/molecules/ProportionalToAttributes/ProportionalToAttributes.stories.tsx b/packages/components/src/components/molecules/ProportionalToAttributes/ProportionalToAttributes.stories.tsx new file mode 100644 index 00000000..6517306c --- /dev/null +++ b/packages/components/src/components/molecules/ProportionalToAttributes/ProportionalToAttributes.stories.tsx @@ -0,0 +1,52 @@ +import React, { useState } from 'react' +import { ComponentMeta, ComponentStory } from '@storybook/react' +import ProportionalToAttributesComponent, { + IProportionalToAttributesValue, +} from './ProportionalToAttributes' + +export default { + title: 'Molecules/ProportionalToAttributesComponent', + component: ProportionalToAttributesComponent, +} as ComponentMeta + +const Template: ComponentStory = ( + args +) => { + const [value, setValue] = useState({ + sourceField: undefined, + boostImpact: undefined, + scaleFactor: 0, + }) + return ( + setValue(value)} + /> + ) +} + +export const ProportionalToAttributes = Template.bind({}) + +ProportionalToAttributes.args = { + boostImpactOptions: [ + { + label: 'Low', + value: 'Low', + }, + { + label: 'Medium', + value: 'Medium', + }, + { + label: 'High', + value: 'High', + }, + ], + sourceFields: [ + { + label: 'test', + value: 'test', + }, + ], +} diff --git a/packages/components/src/components/molecules/ProportionalToAttributes/ProportionalToAttributes.tsx b/packages/components/src/components/molecules/ProportionalToAttributes/ProportionalToAttributes.tsx new file mode 100644 index 00000000..7912d32e --- /dev/null +++ b/packages/components/src/components/molecules/ProportionalToAttributes/ProportionalToAttributes.tsx @@ -0,0 +1,85 @@ +import React from 'react' +import RadioGroup from '../../atoms/form/RadioGroup' +import InputText from '../../atoms/form/InputText' +import DropDown from '../../atoms/form/DropDown' +import { styled } from '@mui/material' +import { IOptions } from '@elastic-suite/gally-admin-shared' +import { useTranslation } from 'next-i18next' + +const Container = styled('div')(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1), +})) + +export interface IProportionalToAttributesValue { + sourceField?: string + boostImpact?: string + scaleFactor: number +} +export interface IProportionalToAttributesProps { + sourceFields: IOptions + boostImpactOptions: IOptions + value: IProportionalToAttributesValue + showError?: boolean + onChange: (value: IProportionalToAttributesValue) => void +} + +function ProportionalToAttributes({ + value, + sourceFields, + boostImpactOptions, + showError, + onChange, +}: IProportionalToAttributesProps): JSX.Element { + const { sourceField, boostImpact, scaleFactor } = value + const { t } = useTranslation('boost') + + function handleChange( + name: keyof IProportionalToAttributesProps['value'], + newValue: string | number + ): void { + onChange({ + ...value, + [name]: newValue, + }) + } + + return ( + + handleChange('sourceField', value)} + required + showError={showError} + sx={{ minWidth: '230px' }} + placeholder={t('boostConfig.sourceField.placeholder')} + /> + + handleChange('boostImpact', value)} + label={t('boostConfig.boostImpact')} + required + showError={showError} + /> + + handleChange('scaleFactor', value)} + showError={showError} + /> + + ) +} + +export default ProportionalToAttributes diff --git a/packages/components/src/components/molecules/ProportionalToAttributes/ProportionalToAttributesManager.tsx b/packages/components/src/components/molecules/ProportionalToAttributes/ProportionalToAttributesManager.tsx new file mode 100644 index 00000000..67b065b2 --- /dev/null +++ b/packages/components/src/components/molecules/ProportionalToAttributes/ProportionalToAttributesManager.tsx @@ -0,0 +1,65 @@ +import React, { useMemo } from 'react' +import { useApiList, useResource } from '../../../hooks' +import ProportionalToAttributes, { + IProportionalToAttributesProps, +} from './ProportionalToAttributes' +import { IOption } from '@elastic-suite/gally-admin-shared' + +function ProportionalToAttributesManager( + props: Omit< + IProportionalToAttributesProps, + 'sourceFields' | 'boostImpactOptions' + > +): JSX.Element { + const rowsPerPage = 200 + const sourceFieldFixedFilters = useMemo( + () => ({ + 'metadata.entity': 'product', + }), + [] + ) + + const boostImpactOptionResource = useResource('BoostImpactOption') + const boostAttributeValueFieldOptionsResource = useResource( + 'BoostAttributeValueFieldOption' + ) + + const [boostImpactOptionsResponse] = useApiList>( + boostImpactOptionResource, + false, + rowsPerPage, + undefined, + undefined, + false, + true + ) + + const [boostAttributeValueFieldOptionsResponse] = useApiList>( + boostAttributeValueFieldOptionsResource, + false, + rowsPerPage, + sourceFieldFixedFilters, + undefined, + false, + true + ) + + if ( + !boostImpactOptionsResponse?.data || + !boostAttributeValueFieldOptionsResponse?.data + ) { + return null + } + + return ( + + ) +} + +export default ProportionalToAttributesManager diff --git a/packages/components/src/components/stateful/FieldGuesser/EditableFieldGuesser.tsx b/packages/components/src/components/stateful/FieldGuesser/EditableFieldGuesser.tsx index 57c9667d..30a982f5 100644 --- a/packages/components/src/components/stateful/FieldGuesser/EditableFieldGuesser.tsx +++ b/packages/components/src/components/stateful/FieldGuesser/EditableFieldGuesser.tsx @@ -28,7 +28,8 @@ import RulesManager from '../RulesManager/RulesManager' import Slider from '../../atoms/form/Slider' import Synonym from '../../atoms/form/Synonym' import Expansion from '../../atoms/form/Expansion' - +import { IProportionalToAttributesValue } from '../../molecules/ProportionalToAttributes/ProportionalToAttributes' +import ProportionalToAttributesManager from '../../molecules/ProportionalToAttributes/ProportionalToAttributesManager' function EditableFieldGuesser(props: IFieldGuesserProps): JSX.Element { const { diffValue, @@ -74,7 +75,8 @@ function EditableFieldGuesser(props: IFieldGuesserProps): JSX.Element { | IRequestType | IRuleCombination | ISynonyms - | IExpansions, + | IExpansions + | IProportionalToAttributesValue, event?: SyntheticEvent ): void { if (onChange) { @@ -331,6 +333,16 @@ function EditableFieldGuesser(props: IFieldGuesserProps): JSX.Element { ) } + case DataContentType.PROPARTIONALTOATTRIBUTE: { + return ( + + ) + } + default: { return } diff --git a/packages/shared/src/services/hydra.ts b/packages/shared/src/services/hydra.ts index e20b5beb..5431ba23 100644 --- a/packages/shared/src/services/hydra.ts +++ b/packages/shared/src/services/hydra.ts @@ -233,6 +233,13 @@ export function inputInitializer(input: string): unknown { case 'ruleEngine': return '{"type":"combination","operator":"all","value":"true","children":[]}' + case 'proportionalToAttribute': + return { + sourceField: undefined, + boostImpact: undefined, + scaleFactor: 0, + } + default: return '' } diff --git a/packages/shared/src/types/customTables.ts b/packages/shared/src/types/customTables.ts index 2de310fe..a0137238 100644 --- a/packages/shared/src/types/customTables.ts +++ b/packages/shared/src/types/customTables.ts @@ -31,6 +31,7 @@ export enum DataContentType { PRODUCTINFO = 'productInfo', BOOSTPREVIEW = 'boostPreview', POSITIONEFFECT = 'positionEffect', + PROPARTIONALTOATTRIBUTE = 'proportionalToAttribute', } export interface ITableHeader extends IFieldConfig {