diff --git a/packages/components/public/locales/fr/api.json b/packages/components/public/locales/fr/api.json
index 7e061923..fa0adca5 100644
--- a/packages/components/public/locales/fr/api.json
+++ b/packages/components/public/locales/fr/api.json
@@ -60,5 +60,7 @@
"Select the localized catalog where the explain will be applied": "Sélection du catalogue localisé sur lequel l'explication' sera appliqué",
"Indicate a term": "Indiquez un terme",
"Search term": "Terme de recherche",
- "Explain and compare": "Explication et comparaison"
+ "Explain and compare": "Explication et comparaison",
+ "Analyzer": "Analyseur",
+ "standard: The textual attribute for searching with possible fuzziness support (if spellcheck = yes).
reference: SKU-like, a sequence of numbers or letters, no understandable text, and no deduction, exact matching...
standard_edge_ngram: standard + support for searching the beginnings of words regardless of the word's length.": "standard: L'attribut textuel permettant une recherche avec un support possible pour les approximations (si spellcheck = yes).
reference:Type similaire à un SKU, une séquence de chiffres ou de lettres, sans texte compréhensible ni déduction, avec correspondance exacte ...
standard_edge_ngram: Standard + support pour rechercher les débuts de mots, quelle que soit la longueur du mot."
}
diff --git a/packages/components/src/components/atoms/form/InfoTooltip.tsx b/packages/components/src/components/atoms/form/InfoTooltip.tsx
index f9a24186..83eb8786 100644
--- a/packages/components/src/components/atoms/form/InfoTooltip.tsx
+++ b/packages/components/src/components/atoms/form/InfoTooltip.tsx
@@ -7,11 +7,31 @@ interface IProps {
title: string | NonNullable
children?: ReactNode
noStyle?: boolean
+ withHTMLTitle?: boolean
}
-function InfoTooltip({ title, children, noStyle }: IProps): JSX.Element {
+function InfoTooltip({
+ title,
+ children,
+ noStyle,
+ withHTMLTitle,
+}: IProps): JSX.Element {
return (
-
+
+ ) : (
+ title
+ )
+ }
+ placement="right"
+ >
{stickyHeader.label}
+ {stickyHeader.gridHeaderInfoTooltip?.trim() ? (
+
+ ) : null}
))}
@@ -135,7 +142,9 @@ function CustomTableHeader(props: IProps): JSX.Element {
whiteSpace: 'nowrap',
...((header.type === DataContentType.SCORE ||
header.type === DataContentType.PRICE) && { width: '10%' }),
- ...(header.type === DataContentType.STOCK && { width: '15%' }),
+ ...(header.type === DataContentType.STOCK && {
+ width: '15%',
+ }),
...(header.type === DataContentType.STRING && {
maxWidth: 'fit-content',
}),
@@ -143,6 +152,12 @@ function CustomTableHeader(props: IProps): JSX.Element {
}}
>
{t(header.label)}
+ {header.gridHeaderInfoTooltip?.trim() ? (
+
+ ) : null}
))}
diff --git a/packages/components/src/components/organisms/CustomTable/CustomTableRow/DraggableRow.tsx b/packages/components/src/components/organisms/CustomTable/CustomTableRow/DraggableRow.tsx
index 80d1cbb2..cd026786 100644
--- a/packages/components/src/components/organisms/CustomTable/CustomTableRow/DraggableRow.tsx
+++ b/packages/components/src/components/organisms/CustomTable/CustomTableRow/DraggableRow.tsx
@@ -9,8 +9,8 @@ import {
ITableHeader,
ITableHeaderSticky,
ITableRow,
- getFieldState,
getImageValue,
+ getPropsFromFieldState,
} from '@elastic-suite/gally-admin-shared'
import {
@@ -130,7 +130,7 @@ function DraggableRow(props: IProps): JSX.Element {
)}
- {stickyHeaders.map((stickyHeader, i) => (
+ {stickyHeaders.map(({ gridHeaderInfoTooltip, ...stickyHeader }, i) => (
))}
- {nonStickyHeaders.map((header) => {
+ {nonStickyHeaders.map(({ gridHeaderInfoTooltip, ...header }) => {
const value =
tableRow[header.name] && header.input === 'image'
? getImageValue(
@@ -167,7 +167,6 @@ function DraggableRow(props: IProps): JSX.Element {
tableRow[header.name] as IImage | string
)
: tableRow[header.name]
-
return (
)}
- {stickyHeaders.map((stickyHeader, i) => {
- return (
-
-
-
- )
- })}
+ {stickyHeaders.map(({ gridHeaderInfoTooltip, ...stickyHeader }, i) => (
+
+
+
+ ))}
- {nonStickyHeaders.map((header) => {
+ {nonStickyHeaders.map(({ gridHeaderInfoTooltip, ...header }) => {
const value =
tableRow[header.name] && header.input === 'image'
? getImageValue(
@@ -172,7 +168,7 @@ function NonDraggableRow(props: IProps): JSX.Element {
onChange={handleChange}
row={tableRow}
value={value}
- {...getFieldState(
+ {...getPropsFromFieldState(
tableRow,
header.depends,
tableConfig[header.name]
diff --git a/packages/components/src/components/stateful/FieldGuesser/EditableFieldGuesser.tsx b/packages/components/src/components/stateful/FieldGuesser/EditableFieldGuesser.tsx
index 2047ee8f..ecac22d0 100644
--- a/packages/components/src/components/stateful/FieldGuesser/EditableFieldGuesser.tsx
+++ b/packages/components/src/components/stateful/FieldGuesser/EditableFieldGuesser.tsx
@@ -2,7 +2,6 @@ import React, { SyntheticEvent } from 'react'
import { useTranslation } from 'next-i18next'
import {
DataContentType,
- IDependsForm,
IExpansions,
IFieldGuesserProps,
IOption,
@@ -23,7 +22,6 @@ import { IDoubleDatePickerValues } from '../../atoms/form/DoubleDatePickerWithou
import DoubleDatePicker from '../../atoms/form/DoubleDatePicker'
import { Box } from '@mui/material'
import RequestTypeManager from '../../stateful/RequestTypeManager/RequestTypeManager'
-import { isHiddenDepends } from '../../../services'
import RulesManager from '../RulesManager/RulesManager'
import Slider from '../../atoms/form/Slider'
import Synonym from '../../atoms/form/Synonym'
@@ -34,7 +32,6 @@ function EditableFieldGuesser(props: IFieldGuesserProps): JSX.Element {
const {
diffValue,
input,
- disabled,
label,
multiple,
name,
@@ -47,7 +44,6 @@ function EditableFieldGuesser(props: IFieldGuesserProps): JSX.Element {
suffix,
type,
validation,
- depends,
requestTypeConfigurations,
data,
optionConfig,
@@ -56,6 +52,7 @@ function EditableFieldGuesser(props: IFieldGuesserProps): JSX.Element {
error,
helperText,
replacementErrorsMessages,
+ disabled,
} = props
const { t } = useTranslation('common')
@@ -87,17 +84,6 @@ function EditableFieldGuesser(props: IFieldGuesserProps): JSX.Element {
}
}
- if (depends) {
- const isHidden = isHiddenDepends(
- depends instanceof Array ? (depends as IDependsForm[]) : [depends],
- data
- )
-
- if (isHidden) {
- return null
- }
- }
-
switch (input ?? type) {
case DataContentType.NUMBER:
case DataContentType.STRING: {
diff --git a/packages/components/src/components/stateful/FieldGuesser/FieldGuesser.tsx b/packages/components/src/components/stateful/FieldGuesser/FieldGuesser.tsx
index ca33a537..efbe17e0 100644
--- a/packages/components/src/components/stateful/FieldGuesser/FieldGuesser.tsx
+++ b/packages/components/src/components/stateful/FieldGuesser/FieldGuesser.tsx
@@ -1,15 +1,25 @@
import React from 'react'
-import { IFieldGuesserProps } from '@elastic-suite/gally-admin-shared'
+import {
+ IFieldGuesserProps,
+ getFieldState,
+} from '@elastic-suite/gally-admin-shared'
import EditableFieldGuesser from './EditableFieldGuesser'
import ReadableFieldGuesser from './ReadableFieldGuesser'
function FieldGuesser(props: IFieldGuesserProps): JSX.Element {
const { editable, ...fieldProps } = props
+ const { visible, ...fieldStateProps } = getFieldState(
+ fieldProps.data,
+ fieldProps.depends
+ )
+
+ if (visible === false) return null
+
if (editable) {
- return
+ return
}
- return
+ return
}
export default FieldGuesser
diff --git a/packages/components/src/components/stateful/FieldGuesser/FormFieldGuesser.tsx b/packages/components/src/components/stateful/FieldGuesser/FormFieldGuesser.tsx
index 560a554b..ba802eb7 100644
--- a/packages/components/src/components/stateful/FieldGuesser/FormFieldGuesser.tsx
+++ b/packages/components/src/components/stateful/FieldGuesser/FormFieldGuesser.tsx
@@ -15,6 +15,7 @@ interface IFormFieldGuesserProps
function FormFieldGuesser(props: IFormFieldGuesserProps): JSX.Element {
const { data, field, ...fieldProps } = props
const value = useValue(field, data)
+
return
}
diff --git a/packages/components/src/hooks/useApiTable.ts b/packages/components/src/hooks/useApiTable.ts
index f0a9babd..6d9390de 100644
--- a/packages/components/src/hooks/useApiTable.ts
+++ b/packages/components/src/hooks/useApiTable.ts
@@ -30,11 +30,12 @@ export function useApiHeadersForm(
resource: IResource
): IFieldConfigFormWithFieldset[] {
const apiHeaders = useApiHeaders(resource)
+
return useMemo(() => {
const apiHeaderMap = apiHeaders.reduce<
Record
>(
- (acc, header) => {
+ (acc, { gridHeaderInfoTooltip, ...header }) => {
const fieldsetCode = header.fieldset
const fieldset = resource.gally?.fieldset?.[fieldsetCode]
if (fieldsetCode && fieldset) {
diff --git a/packages/components/src/services/form.ts b/packages/components/src/services/form.ts
index f1aaab9d..cfaf7ffa 100644
--- a/packages/components/src/services/form.ts
+++ b/packages/components/src/services/form.ts
@@ -1,5 +1,4 @@
import {
- IDependsForm,
IFetch,
IFieldConfig,
IHydraResponse,
@@ -29,20 +28,6 @@ export function getDoubleDatePickerValue(
return { fromDate: data?.fromDate, toDate: data?.toDate }
}
-export function isHiddenDepends(
- dependsForm: IDependsForm[],
- data: Record | undefined
-): boolean {
- return dependsForm.some((item) => {
- const field = item?.field as string
- const { value } = item
- const fieldValue = data?.[field]
- return (
- fieldValue === undefined || (value !== fieldValue && value !== undefined)
- )
- })
-}
-
export function getRequestTypeData(
data?: Record,
limitationTypeOptionsApi?: IFetch>
diff --git a/packages/shared/src/services/field.test.ts b/packages/shared/src/services/field.test.ts
index 2360474a..b616225e 100644
--- a/packages/shared/src/services/field.test.ts
+++ b/packages/shared/src/services/field.test.ts
@@ -147,7 +147,7 @@ describe('Field service', () => {
expect(
getFieldState(
{ foo: 'bar', baz: true },
- { conditions: { baz: true }, disabled: true }
+ { conditions: { field: 'baz', value: false }, type: 'enabled' }
)
).toEqual({ disabled: true })
})
@@ -159,7 +159,7 @@ describe('Field service', () => {
expect(
getFieldState(
{ foo: 'bar', baz: true },
- { conditions: { baz: true }, disabled: true },
+ { conditions: { field: 'baz', value: true }, type: 'enabled' },
{ disabled: false }
)
).toEqual({ disabled: false })
diff --git a/packages/shared/src/services/field.ts b/packages/shared/src/services/field.ts
index 2f6bbaea..5890b3f1 100644
--- a/packages/shared/src/services/field.ts
+++ b/packages/shared/src/services/field.ts
@@ -5,6 +5,7 @@ import {
IFieldCondition,
IFieldConfig,
IFieldConfigFormWithFieldset,
+ IFieldDepends,
IFieldState,
} from '../types'
@@ -59,24 +60,76 @@ export function isDropdownStaticOptions(
return 'values' in options
}
-export function getFieldState(
+/**
+ * It works like an "or" for the first level, but if we have an array at the second level then it works like an "and" (all conditions must be true)
+ */
+function isConditionActive(
entity: Record,
- depends?: IFieldCondition,
+ conditions: (IFieldCondition | IFieldCondition[])[] | IFieldCondition
+): boolean {
+ if (!Array.isArray(conditions)) {
+ return entity[conditions.field] === conditions.value
+ }
+ let conditionActive = false
+ let index = 0
+ while (!conditionActive && index < conditions.length) {
+ const item = conditions[index]
+ if (Array.isArray(item)) {
+ conditionActive = item.every(
+ ({ field, value }) => entity[field] === value
+ )
+ } else {
+ const { field, value } = item
+ conditionActive = entity[field] === value
+ }
+ index++
+ }
+ return conditionActive
+}
+
+/**
+ * Allows to return a state based on conditions dependent on another field.
+ * The field [field name] depends on the condition [condition] to be [type].
+ */
+export function getFieldState(
+ entity?: Record,
+ depends?: IFieldDepends,
state: IFieldState = {}
): IFieldState {
+ if (!entity) return {}
if (!depends?.conditions) {
return state
}
- const { conditions, ...conditionalState } = depends
- const conditionActive = Object.entries(conditions).every(
- ([field, value]) => entity[field] === value
- )
+ const { conditions, type } = depends
+
+ const newState: IFieldState = {}
+
+ switch (type) {
+ case 'visible':
+ newState.visible = isConditionActive(entity, conditions)
+ break
+ case 'enabled':
+ newState.disabled = !isConditionActive(entity, conditions)
+ }
+
return {
- ...(conditionActive && conditionalState),
+ ...newState,
...state,
}
}
+/**
+ * return fieldState without the states that are not field props like "visible"
+ */
+export function getPropsFromFieldState(
+ entity?: Record,
+ depends?: IFieldDepends,
+ state: IFieldState = {}
+): Omit {
+ const { visible, ...otherProps } = getFieldState(entity, depends, state)
+ return otherProps
+}
+
export function isFieldConfigFormWithFieldset(
fieldConfig: IFieldConfig | IFieldConfigFormWithFieldset
): fieldConfig is IFieldConfigFormWithFieldset {
diff --git a/packages/shared/src/services/form.ts b/packages/shared/src/services/form.ts
index 4595be9e..a3a87fc9 100644
--- a/packages/shared/src/services/form.ts
+++ b/packages/shared/src/services/form.ts
@@ -1,7 +1,6 @@
import { TFunction } from 'next-i18next'
import {
IExpansions,
- IField,
IRequestType,
IRequestTypesOptions,
ISearchLimitations,
@@ -138,14 +137,3 @@ export function getExpansionsErrorMessages(expansions: IExpansions): string[] {
export function areExpansionsValid(expansions: IExpansions): boolean {
return getExpansionsErrorMessages(expansions).length === 0
}
-
-export function isDependsField(
- field: IField,
- data: Record
-): boolean {
- return (
- !field?.gally?.depends ||
- (field.gally.depends?.field in data &&
- data[field.gally.depends.field] === field.gally.depends?.value)
- )
-}
diff --git a/packages/shared/src/services/table.ts b/packages/shared/src/services/table.ts
index 9f4cfded..c079aa5d 100644
--- a/packages/shared/src/services/table.ts
+++ b/packages/shared/src/services/table.ts
@@ -120,6 +120,7 @@ export function getFieldHeader(field: IField, t: TFunction): IFieldConfig {
...fieldConfig,
editable: field.gally?.editable && field.writeable,
fieldset: field.gally?.fieldset,
+ gridHeaderInfoTooltip: field.gally?.gridHeaderInfoTooltip,
id,
input,
infoTooltip: field.gally?.infoTooltip,
diff --git a/packages/shared/src/types/field.ts b/packages/shared/src/types/field.ts
index c66e0fb6..23e38702 100644
--- a/packages/shared/src/types/field.ts
+++ b/packages/shared/src/types/field.ts
@@ -5,17 +5,23 @@ import { DataContentType, ITableRow } from './customTables'
import { IMultipleInputConfiguration, IMultipleValueFormat } from './hydra'
import { IOption, IOptions } from './option'
-export interface IFieldCondition {
- conditions: Record
+export interface IFieldState {
disabled?: boolean
+ visible?: boolean
}
-export interface IFieldState {
- disabled?: boolean
+export interface IFieldCondition {
+ field: string
+ value: any
+}
+
+export interface IFieldDepends {
+ type: 'enabled' | 'visible'
+ conditions: (IFieldCondition | IFieldCondition[])[] | IFieldCondition
}
export interface IFieldConfig extends IFieldState {
- depends?: any
+ depends?: IFieldDepends
editable?: boolean
field?: IField
fieldset?: string
@@ -42,6 +48,7 @@ export interface IFieldConfig extends IFieldState {
cellsStyle?: CSSProperties
showError?: boolean
replacementErrorsMessages?: Record
+ gridHeaderInfoTooltip?: string
}
export interface IFieldConfigFormWithFieldset {
diff --git a/packages/shared/src/types/hydra.ts b/packages/shared/src/types/hydra.ts
index 4704912f..b8c2d51d 100644
--- a/packages/shared/src/types/hydra.ts
+++ b/packages/shared/src/types/hydra.ts
@@ -11,7 +11,7 @@ import {
} from './jsonld'
import { IOptions } from './option'
import { IHydraSimpleCatalog } from './catalog'
-import { IFieldGuesserProps } from './field'
+import { IFieldDepends, IFieldGuesserProps } from './field'
export enum HydraType {
ARRAY = 'array',
@@ -112,7 +112,7 @@ export interface IMultipleValueFormat {
export interface IGallyProperty {
context?: Record
- depends?: any
+ depends?: IFieldDepends
editable?: boolean
input?: string
options?: IDropdownOptions & (IDropdownStaticOptions | IDropdownApiOptions)
@@ -134,6 +134,7 @@ export interface IGallyProperty {
placeholder?: string
defaultValue?: unknown
showError?: boolean
+ gridHeaderInfoTooltip?: string
}
export interface IDropdownOptions {
objectKeyValue?: string