Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor FormItem (label translation) #3596

Merged
merged 10 commits into from
Oct 15, 2024
4 changes: 1 addition & 3 deletions webapp/components/DataQuery/ButtonBar/ButtonBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
DataExplorerState,
} from '@webapp/store/dataExplorer'
import { useAuthCanCleanseRecords } from '@webapp/store/user'
import { useI18n } from '@webapp/store/system'

import { DataQueryExportModal } from '../DataQueryExportModal'
import { State, useButtonBar } from './store'
Expand All @@ -42,7 +41,6 @@ const ButtonBar = (props) => {
} = props

const dispatch = useDispatch()
const i18n = useI18n()
const appSaving = useIsAppSaving()
const canEdit = useAuthCanCleanseRecords()
const displayType = DataExplorerSelectors.useDisplayType()
Expand All @@ -67,7 +65,7 @@ const ButtonBar = (props) => {
variant="outlined"
/>

<FormItem className="mode-form-item" label={i18n.t('dataView.dataQuery.mode.label')}>
<FormItem className="mode-form-item" label="dataView.dataQuery.mode.label">
<ButtonGroup
disabled={appSaving || !nodeDefsSelectorVisible}
groupName="queryMode"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { DataQuerySummaries } from '@openforis/arena-core'
import * as StringUtils from '@core/stringUtils'
import * as Validation from '@core/validation/validation'

import { useI18n } from '@webapp/store/system'
import { DataExplorerSelectors } from '@webapp/store/dataExplorer'

import { FormItem, Input } from '@webapp/components/form/Input'
Expand All @@ -16,15 +15,13 @@ import { ButtonDelete, ButtonNew, ButtonSave } from '@webapp/components/buttons'
export const DataQueryEditForm = (props) => {
const { draft, querySummary, setQuerySummary, onDelete, onNew, onSave, validating } = props

const i18n = useI18n()

const validation = Validation.getValidation(querySummary)

const selectedQuerySummaryUuid = DataExplorerSelectors.useSelectedQuerySummaryUuid()

return (
<div className="data-query-form">
<FormItem label={i18n.t('common.name')}>
<FormItem label="common.name">
<Input
onChange={(value) =>
setQuerySummary(DataQuerySummaries.assocName(StringUtils.normalizeName(value))(querySummary))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@ import { FormItem } from '@webapp/components/form/Input'
import { useSortable } from '@webapp/components/hooks'

import { useNodeDefsByUuids } from '@webapp/store/survey'
import { useI18n } from '@webapp/store/system'

import { DataQuerySortableItemChip } from './DataQuerySortableItemChip'

export const DataQuerySortableItems = (props) => {
const { nodeDefUuids, label, nodeDefLabelType, onItemsSort, onItemDelete } = props

const i18n = useI18n()
const containerRef = useRef(null)
const nodeDefs = useNodeDefsByUuids(nodeDefUuids)

Expand All @@ -31,7 +29,7 @@ export const DataQuerySortableItems = (props) => {
if (nodeDefs.length === 0) return null

return (
<FormItem className="data-query__sortable-items-form-item" info="dataView.sortableItemsInfo" label={i18n.t(label)}>
<FormItem className="data-query__sortable-items-form-item" info="dataView.sortableItemsInfo" label={label}>
<div className="data-query__sortable-items-wrapper" ref={containerRef}>
{nodeDefs.map((nodeDef) => (
<DataQuerySortableItemChip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,23 @@ import { useSurvey, useSurveyCycleKey } from '@webapp/store/survey'
import { useI18n } from '@webapp/store/system'
import { RecordKeyValuesExtractor } from '@webapp/views/App/views/Data/Records/recordKeyValuesExtractor'

const FormItem = ({ label, children }) => (
<div className="tooltip-form-item">
<div className="tooltip-form-label">{label}:</div>
<div className="tooltip-form-value">{children}</div>
</div>
)
const FormItem = ({ label, children }) => {
const i18n = useI18n()

return (
<div className="tooltip-form-item">
<div className="tooltip-form-label">{i18n.t(label)}:</div>
<div className="tooltip-form-value">{children}</div>
</div>
)
}

FormItem.propTypes = {
label: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
}

const RecordInfoFormItems = ({ recordUuid }) => {
const i18n = useI18n()
const survey = useSurvey()
const cycle = useSurveyCycleKey()

Expand Down Expand Up @@ -53,8 +56,8 @@ const RecordInfoFormItems = ({ recordUuid }) => {

return (
<>
<FormItem label={i18n.t('common.record')}>{loading ? '...' : recordKeys}</FormItem>
<FormItem label={i18n.t('common.owner')}>{loading ? '...' : recordOwner}</FormItem>
<FormItem label="common.record">{loading ? '...' : recordKeys}</FormItem>
<FormItem label="common.owner">{loading ? '...' : recordOwner}</FormItem>
</>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { validateAggregateFunction } from '@core/survey/aggregateFunctionValidat
import * as StringUtils from '@core/stringUtils'
import * as Validation from '@core/validation/validation'

import { useI18n } from '@webapp/store/system'

import { FormItem, Input } from '@webapp/components/form/Input'
import { ButtonCancel, ButtonDelete, ButtonSave } from '@webapp/components'
import { NotificationActions } from '@webapp/store/ui'
Expand All @@ -25,7 +23,6 @@ export const CustomAggregateFunctionEditor = (props) => {
} = props

const dispatch = useDispatch()
const i18n = useI18n()

const [aggregateFunction, setAggregateFunction] = useState(aggregateFunctionParam)

Expand Down Expand Up @@ -58,7 +55,7 @@ export const CustomAggregateFunctionEditor = (props) => {

return (
<div className="form">
<FormItem label={i18n.t('common.name')}>
<FormItem label="common.name">
<Input
validation={Validation.getFieldValidation(AggregateFunction.keys.name)(validation)}
value={name}
Expand All @@ -67,7 +64,7 @@ export const CustomAggregateFunctionEditor = (props) => {
}
/>
</FormItem>
<FormItem label={i18n.t('dataExplorerView.customAggregateFunction.sqlExpression')}>
<FormItem label="dataExplorerView.customAggregateFunction.sqlExpression">
<AggregateFunctionExpressionEditor
entityDef={entityDef}
nodeDef={nodeDef}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@ import { Dropdown } from '@webapp/components/form'
import { FormItem } from '@webapp/components/form/Input'
import { CategorySelector } from '@webapp/components/survey/CategorySelector'
import { useSurvey } from '@webapp/store/survey'
import { useI18n } from '@webapp/store/system'
import { useCategoryByName, useNodeDefsByNames } from '@webapp/store/survey/hooks'

import { CallEditorPropTypes } from './callEditorPropTypes'

const CategoryLevelVariable = (props) => {
const { disabled, hierarchicalCategory, level, onChange, selectedAttributeUuid, variables } = props

const i18n = useI18n()
const survey = useSurvey()

const levelUuid = CategoryLevel.getUuid(level)
Expand All @@ -45,9 +43,8 @@ const CategoryLevelVariable = (props) => {
return (
<FormItem
key={levelUuid}
label={i18n.t(hierarchicalCategory ? 'nodeDefEdit.filterVariableForLevel' : 'nodeDefEdit.filterVariable', {
levelName: CategoryLevel.getName(level),
})}
label={hierarchicalCategory ? 'nodeDefEdit.filterVariableForLevel' : 'nodeDefEdit.filterVariable'}
labelParams={{ levelName: CategoryLevel.getName(level) }}
>
<Dropdown
className="identifier"
Expand Down Expand Up @@ -86,7 +83,6 @@ const createInitialState = ({ initialCategory, initialCategoryPropKey, initialAt
export const CallCategoryItemPropEditor = (props) => {
const { expressionNode, onConfirm: onConfirmProp, variables } = props

const i18n = useI18n()
const survey = useSurvey()

const expressionArgumentsValues =
Expand Down Expand Up @@ -139,7 +135,7 @@ export const CallCategoryItemPropEditor = (props) => {

return (
<div className="function-editor">
<FormItem label={i18n.t('nodeDefEdit.codeProps.category')}>
<FormItem label="nodeDefEdit.codeProps.category">
<CategorySelector
categoryUuid={categoryUuid}
filterFunction={Category.hasExtraDefs}
Expand All @@ -149,7 +145,7 @@ export const CallCategoryItemPropEditor = (props) => {
showManage={false}
/>
</FormItem>
<FormItem label={i18n.t('extraProp.label')}>
<FormItem label="extraProp.label">
<Dropdown
disabled={!categoryUuid}
items={Category.getItemExtraDefKeys(category)}
Expand Down
7 changes: 2 additions & 5 deletions webapp/components/expression/nodes/call/callIncludesEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { Button } from '@webapp/components/buttons'
import { FormItem } from '@webapp/components/form/Input'

import { useNodeDefByName } from '@webapp/store/survey/hooks'
import { useI18n } from '@webapp/store/system'

import Identifier from '../identifier'
import Literal from '../literal'
Expand All @@ -16,8 +15,6 @@ import { CallEditorPropTypes } from './callEditorPropTypes'
export const CallIncludesEditor = (props) => {
const { expressionNode, onConfirm: onConfirmProp, variables } = props

const i18n = useI18n()

const [expressionNodeArg1, expressionNodeArg2] = expressionNode?.arguments ?? []

const [state, setState] = useState({
Expand Down Expand Up @@ -62,7 +59,7 @@ export const CallIncludesEditor = (props) => {

return (
<div className="function-editor">
<FormItem label={i18n.t('expressionEditor.var')}>
<FormItem label="expressionEditor.var">
<Identifier
node={identifierParam}
onChange={onIdentifierParamChange}
Expand All @@ -73,7 +70,7 @@ export const CallIncludesEditor = (props) => {
/>
</FormItem>
{identifierNodeDef && (
<FormItem label={i18n.t('common.value')}>
<FormItem label="common.value">
<Literal node={literalParam} nodeDefCurrent={identifierNodeDef} onChange={onLiteralParamChange} />
</FormItem>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@ import React, { useCallback, useState } from 'react'
import * as Expression from '@core/expressionParser/expression'

import { FormItem } from '@webapp/components/form/Input'
import { useI18n } from '@webapp/store/system'

import Identifier from '../identifier'
import { CallEditorPropTypes } from './callEditorPropTypes'

export const CallSingleParameterEditor = (props) => {
const { callee, expressionNode, onConfirm: onConfirmProp, variables, variablesFilterFn } = props

const i18n = useI18n()
const initialIdentifierName = expressionNode?.arguments?.[0]?.name
const initialIdentifier = initialIdentifierName ? Expression.newIdentifier(initialIdentifierName) : null

Expand All @@ -38,7 +36,7 @@ export const CallSingleParameterEditor = (props) => {
)

return (
<FormItem label={i18n.t('expressionEditor.var')}>
<FormItem label="expressionEditor.var">
<Identifier
node={identifier}
onChange={onIdentifierChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import * as StringUtils from '@core/stringUtils'
import { Button } from '@webapp/components/buttons'
import { Dropdown } from '@webapp/components/form'
import { FormItem } from '@webapp/components/form/Input'
import { useI18n } from '@webapp/store/system'
import { TaxonomySelector } from '@webapp/components/survey/TaxonomySelector'
import { useTaxonomyByName, useTaxonomyByUuid } from '@webapp/store/survey/hooks'

Expand All @@ -28,8 +27,6 @@ const createInitialState = ({ initialTaxonomy, initialExtraPropKey, initialIdent
export const CallTaxonPropEditor = (props) => {
const { expressionNode, onConfirm: onConfirmProp, variables } = props

const i18n = useI18n()

const expressionArgumentsValues =
expressionNode?.arguments?.map((arg) => arg.value ?? arg.name).map(StringUtils.unquote) ?? []
const [initialTaxonomyName, initialExtraPropKey, initialIdentifierName] = expressionArgumentsValues
Expand Down Expand Up @@ -67,7 +64,7 @@ export const CallTaxonPropEditor = (props) => {

return (
<div className="function-editor">
<FormItem label={i18n.t('taxonomy.header')}>
<FormItem label="taxonomy.header">
<TaxonomySelector
filterFunction={Taxonomy.hasExtraDefs}
onChange={(item) => {
Expand All @@ -81,7 +78,7 @@ export const CallTaxonPropEditor = (props) => {
selectedTaxonomyUuid={taxonomyUuid}
/>
</FormItem>
<FormItem label={i18n.t('extraProp.label')}>
<FormItem label="extraProp.label">
<Dropdown
disabled={!taxonomyUuid}
items={Taxonomy.getExtraPropKeys(taxonomy)}
Expand All @@ -97,7 +94,7 @@ export const CallTaxonPropEditor = (props) => {
/>
</FormItem>

<FormItem label={i18n.t('expressionEditor.var')}>
<FormItem label="expressionEditor.var">
<Identifier disabled={!taxonomyUuid} node={identifier} onChange={onIdentifierChange} variables={variables} />
</FormItem>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ import * as Expression from '@core/expressionParser/expression'

import { Button } from '@webapp/components/buttons'
import { FormItem, Input } from '@webapp/components/form/Input'
import { useI18n } from '@webapp/store/system'

import { CallEditorPropTypes } from './callEditorPropTypes'

export const CallUserPropEditor = (props) => {
const { expressionNode, onConfirm: onConfirmProp } = props

const i18n = useI18n()
const initialValue = expressionNode?.arguments?.[0]?.value

const [value, setValue] = useState(initialValue)
Expand All @@ -32,7 +30,7 @@ export const CallUserPropEditor = (props) => {

return (
<div className="function-editor">
<FormItem label={i18n.t('extraProp.label')}>
<FormItem label="extraProp.label">
<Input onChange={setValue} textTransformFunction={StringUtils.normalizeName} value={value} />
</FormItem>
<Button disabled={Objects.isEmpty(value)} label="common.ok" onClick={onConfirm} />
Expand Down
24 changes: 21 additions & 3 deletions webapp/components/form/Input/FormItem.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
import React from 'react'
import classNames from 'classnames'
import PropTypes from 'prop-types'

import { Objects } from '@openforis/arena-core'

import { ButtonIconInfo } from '@webapp/components/buttons'
import { useI18n } from '@webapp/store/system'

export const FormItem = (props) => {
const { children, className = '', info = null, label = null, required = false } = props
const {
children,
className = '',
info = null,
label: labelProp = null,
labelParams = null,
onInfoClick = null,
required = false,
} = props

const i18n = useI18n()
const label =
Objects.isNotEmpty(labelProp) && typeof labelProp === 'string' ? i18n.t(labelProp, labelParams) : labelProp

return (
<div className={`form-item ${className}`}>
<div className={classNames('form-item', className)}>
<div className="form-label">
<div className="form-label-wrapper">
{label}
{required ? ' *' : ''}
{info && <ButtonIconInfo title={info} />}
{info && <ButtonIconInfo onClick={onInfoClick} title={info} />}
</div>
</div>
{children}
Expand All @@ -25,5 +41,7 @@ FormItem.propTypes = {
children: PropTypes.oneOfType([PropTypes.string, PropTypes.element, PropTypes.arrayOf(PropTypes.element)]).isRequired,
info: PropTypes.string,
label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
labelParams: PropTypes.object,
onInfoClick: PropTypes.func,
required: PropTypes.bool,
}
Loading
Loading