diff --git a/core/i18n/resources/en.js b/core/i18n/resources/en.js
index f24891d416..fdfd8955cb 100644
--- a/core/i18n/resources/en.js
+++ b/core/i18n/resources/en.js
@@ -1153,6 +1153,16 @@ E.g. this.region = region_attribute_name
other: 'Other',
},
},
+ formHeaderProps: {
+ headerColorLabel: 'Header color',
+ headerColor: {
+ blue: 'Blue',
+ green: 'Green',
+ orange: 'Orange',
+ red: 'Red',
+ yellow: 'Yellow',
+ },
+ },
textProps: {
textInputType: 'Text input type',
textInputTypes: {
@@ -1236,6 +1246,8 @@ E.g. this.region = region_attribute_name
taxon: 'Taxon',
text: 'Text',
time: 'Time',
+ // layout elments
+ formHeader: 'Form Header',
},
clone: `Clone '{{nodeDefLabel}}'`,
compressFormItems: `Compress form items for '{{nodeDefLabel}}'`,
diff --git a/core/survey/_survey/surveyNodeDefs.js b/core/survey/_survey/surveyNodeDefs.js
index c0d6b08e34..9c6dbaa364 100644
--- a/core/survey/_survey/surveyNodeDefs.js
+++ b/core/survey/_survey/surveyNodeDefs.js
@@ -42,26 +42,31 @@ const filterNodeDefsWithoutSiblings = (nodeDefs) =>
)
export const getNodeDefChildren =
- (nodeDef, includeAnalysis = true) =>
+ (nodeDef, includeAnalysis = true, includeLayoutElements = false) =>
(survey) => {
const surveyIndexed = survey.nodeDefsIndex ? survey : SurveyNodeDefsIndex.initAndAssocNodeDefsIndex(survey)
- let childDefs = Surveys.getNodeDefChildren({ survey: surveyIndexed, nodeDef, includeAnalysis })
+ let childDefs = Surveys.getNodeDefChildren({
+ survey: surveyIndexed,
+ nodeDef,
+ includeAnalysis,
+ includeLayoutElements,
+ })
childDefs = filterNodeDefsWithoutSiblings(childDefs)
return childDefs
}
export const getNodeDefChildrenSorted =
- ({ nodeDef, includeAnalysis = false, cycle = null }) =>
+ ({ nodeDef, includeAnalysis = false, cycle = null, includeLayoutElements = false }) =>
(survey) => {
- let childDefs = Surveys.getNodeDefChildrenSorted({ survey, nodeDef, includeAnalysis, cycle })
+ let childDefs = Surveys.getNodeDefChildrenSorted({ survey, cycle, nodeDef, includeAnalysis, includeLayoutElements })
childDefs = filterNodeDefsWithoutSiblings(childDefs)
return childDefs
}
export const getNodeDefChildrenInOwnPage =
- ({ nodeDef, cycle }) =>
+ ({ nodeDef, cycle, includeAnalysis = true, includeLayoutElements = false }) =>
(survey) => {
- const children = getNodeDefChildren(nodeDef)(survey)
+ const children = getNodeDefChildren(nodeDef, includeAnalysis, includeLayoutElements)(survey)
const childrenInOwnPage = children.filter(NodeDefLayout.hasPage(cycle))
const childrenIndex = NodeDefLayout.getIndexChildren(cycle)(nodeDef)
if (childrenIndex.length === 0) return childrenInOwnPage
diff --git a/core/survey/nodeDef.js b/core/survey/nodeDef.js
index 6dbd36b0c0..07056294e6 100644
--- a/core/survey/nodeDef.js
+++ b/core/survey/nodeDef.js
@@ -20,6 +20,8 @@ import { valuePropsTaxon } from './nodeValueProps'
export { nodeDefType }
+export const NodeDefLayoutElementTypes = [nodeDefType.formHeader]
+
export const keys = {
id: ObjectUtils.keys.id,
uuid: ObjectUtils.keys.uuid,
@@ -87,6 +89,9 @@ export const propKeys = {
includeAccuracy: 'includeAccuracy',
includeAltitude: 'includeAltitude',
includeAltitudeAccuracy: 'includeAltitudeAccuracy',
+
+ // layout elements
+ headerColor: 'headerColor',
}
export const textInputTypes = {
@@ -203,6 +208,8 @@ export const isInteger = isType(nodeDefType.integer)
export const isTaxon = isType(nodeDefType.taxon)
export const isText = isType(nodeDefType.text)
export const isTime = isType(nodeDefType.time)
+// layout elments
+export const isFormHeader = isType(nodeDefType.formHeader)
export const isReadOnly = getProp(propKeys.readOnly, false)
export const isHidden = getProp(propKeys.hidden, false)
@@ -250,6 +257,11 @@ export const getTextTransform = getProp(propKeys.textTransform, textTransformVal
export const getTextTransformFunction = (nodeDef) =>
TextUtils.transform({ transformFunction: getTextTransform(nodeDef) })
+// layout elements
+
+export const getHeaderColor = getProp(propKeys.headerColor)
+export const isLayoutElement = isFormHeader
+
// ==== READ meta
export const getMeta = R.propOr({}, keys.meta)
export const getMetaHierarchy = R.pathOr([], [keys.meta, metaKeys.h])
@@ -502,8 +514,9 @@ export const keepOnlyOneCycle =
export const canNodeDefBeMultiple = (nodeDef) =>
// Entity def but not root
(isEntity(nodeDef) && !isRoot(nodeDef)) ||
- // Attribute def but not analysis
- (!isAnalysis(nodeDef) &&
+ // Attribute def but not layout element and not analysis
+ (!isLayoutElement(nodeDef) &&
+ !isAnalysis(nodeDef) &&
R.includes(getType(nodeDef), [
nodeDefType.decimal,
nodeDefType.code,
@@ -523,7 +536,8 @@ export const canNodeDefTypeBeKey = (type) =>
nodeDefType.time,
])
-export const canNodeDefBeKey = (nodeDef) => !isAnalysis(nodeDef) && canNodeDefTypeBeKey(getType(nodeDef))
+export const canNodeDefBeKey = (nodeDef) =>
+ !isLayoutElement(nodeDef) && !isAnalysis(nodeDef) && canNodeDefTypeBeKey(getType(nodeDef))
export const canHaveDefaultValue = (nodeDef) =>
isSingleAttribute(nodeDef) &&
diff --git a/core/survey/nodeDefType.js b/core/survey/nodeDefType.js
index 631625d827..b657e97082 100644
--- a/core/survey/nodeDefType.js
+++ b/core/survey/nodeDefType.js
@@ -10,4 +10,6 @@ export const nodeDefType = {
taxon: 'taxon',
file: 'file',
entity: 'entity',
+ // layout elements
+ formHeader: 'formHeader',
}
diff --git a/package.json b/package.json
index 2507ccf58a..9c2fb3e5cd 100644
--- a/package.json
+++ b/package.json
@@ -106,7 +106,7 @@
"@mui/material": "^5.14.18",
"@mui/x-data-grid": "^6.18.1",
"@mui/x-date-pickers": "^6.18.1",
- "@openforis/arena-core": "^0.0.175",
+ "@openforis/arena-core": "^0.0.177",
"@openforis/arena-server": "^0.1.30",
"@sendgrid/mail": "^7.7.0",
"@shopify/draggable": "^1.1.3",
diff --git a/server/modules/record/service/update/thread/recordsUpdateThread.js b/server/modules/record/service/update/thread/recordsUpdateThread.js
index 19e9476a3c..05ded6916a 100644
--- a/server/modules/record/service/update/thread/recordsUpdateThread.js
+++ b/server/modules/record/service/update/thread/recordsUpdateThread.js
@@ -160,8 +160,11 @@ class RecordsUpdateThread extends Thread {
const { survey, recordsCache } = await this.getOrFetchSurveyData(msg)
+ console.log('===init record', recordUuid)
let record = await RecordManager.fetchRecordAndNodesByUuid({ surveyId, recordUuid })
+ console.log('===record1', record)
+
record = await RecordManager.initNewRecord({
user,
survey,
@@ -170,6 +173,7 @@ class RecordsUpdateThread extends Thread {
nodesUpdateListener: (updatedNodes) => this.handleNodesUpdated.bind(this)({ record, updatedNodes }),
nodesValidationListener: (validations) => this.handleNodesValidationUpdated.bind(this)({ record, validations }),
})
+ console.log('===record2', record)
recordsCache.set(recordUuid, record)
}
diff --git a/test/e2e/tests/login.js b/test/e2e/tests/login.js
index d62fe9e856..0771de7820 100644
--- a/test/e2e/tests/login.js
+++ b/test/e2e/tests/login.js
@@ -25,7 +25,7 @@ export default () =>
page.click('text="Login"'),
])
- const header = await page.$('.header')
+ const header = await page.$('.app-header')
await expect(header).not.toBe(null)
})
})
diff --git a/test/e2e/tests/utils/formUtils.js b/test/e2e/tests/utils/formUtils.js
index f0569112ea..efae2150cc 100644
--- a/test/e2e/tests/utils/formUtils.js
+++ b/test/e2e/tests/utils/formUtils.js
@@ -61,7 +61,7 @@ const expectDropdownValue = async ({ testId = null, parentSelector = '', value }
const waitForLoaderToDisappear = async () => page.waitForSelector('.loader', { state: 'hidden', timeout: 5000 })
const waitForHeaderLoaderToDisappear = async () =>
- page.waitForSelector('.header__loader-wrapper', { state: 'hidden', timeout: 5000 })
+ page.waitForSelector('.app-header__loader-wrapper', { state: 'hidden', timeout: 5000 })
export const FormUtils = {
selectDropdownItem,
diff --git a/webapp/components/form/buttonGroup.js b/webapp/components/form/buttonGroup.js
index 7a3e075d52..4a2f1b7097 100644
--- a/webapp/components/form/buttonGroup.js
+++ b/webapp/components/form/buttonGroup.js
@@ -5,36 +5,54 @@ import PropTypes from 'prop-types'
import * as R from 'ramda'
-const ButtonGroup = ({ items, groupName, multiple, selectedItemKey, onChange, disabled, deselectable, className }) => (
+const ButtonGroup = ({
+ items,
+ groupName,
+ multiple,
+ selectedItemKey,
+ onChange,
+ disabled: disabledProp,
+ deselectable,
+ className,
+}) => (
{items.map((item) => {
- const selected = selectedItemKey === item.key || (multiple && R.includes(item.key, selectedItemKey))
+ const { key, disabled, icon, label } = item
+ const selected = selectedItemKey === key || (multiple && R.includes(key, selectedItemKey))
return (
)
})}
)
+export const toButtonGroupItems = ({ i18n, object, labelPrefix, icon = null }) =>
+ Object.keys(object).map((key) => ({
+ key,
+ label: i18n.t(`${labelPrefix}${key}`),
+ icon,
+ }))
+
ButtonGroup.propTypes = {
items: PropTypes.array,
groupName: PropTypes.string,
diff --git a/webapp/components/survey/NodeDefDetails/BasicProps/BasicProps.js b/webapp/components/survey/NodeDefDetails/BasicProps/BasicProps.js
index e4c38d1665..a5eb5ebbea 100644
--- a/webapp/components/survey/NodeDefDetails/BasicProps/BasicProps.js
+++ b/webapp/components/survey/NodeDefDetails/BasicProps/BasicProps.js
@@ -27,6 +27,7 @@ import CodeProps from '../CodeProps'
import CoordinateProps from '../CoordinateProps'
import DecimalProps from '../DecimalProps'
import FileProps from '../FileProps'
+import FormHeaderProps from '../FormHeaderProps'
import TaxonProps from '../TaxonProps'
import TextProps from '../TextProps'
import AnalysisProps from '../AnalysisProps'
@@ -37,6 +38,7 @@ const basicPropsComponentByType = {
[NodeDef.nodeDefType.coordinate]: CoordinateProps,
[NodeDef.nodeDefType.decimal]: DecimalProps,
[NodeDef.nodeDefType.file]: FileProps,
+ [NodeDef.nodeDefType.formHeader]: FormHeaderProps,
[NodeDef.nodeDefType.taxon]: TaxonProps,
[NodeDef.nodeDefType.text]: TextProps,
}
diff --git a/webapp/components/survey/NodeDefDetails/FormHeaderProps.js b/webapp/components/survey/NodeDefDetails/FormHeaderProps.js
new file mode 100644
index 0000000000..bb258c326d
--- /dev/null
+++ b/webapp/components/survey/NodeDefDetails/FormHeaderProps.js
@@ -0,0 +1,61 @@
+import './FormHeaderProps.scss'
+
+import React, { useCallback } from 'react'
+import PropTypes from 'prop-types'
+
+import { FormHeaderColor } from '@openforis/arena-core'
+
+import * as NodeDef from '@core/survey/nodeDef'
+
+import { useI18n } from '@webapp/store/system'
+import { FormItem } from '@webapp/components/form/Input'
+import ButtonGroup, { toButtonGroupItems } from '@webapp/components/form/buttonGroup'
+
+import { headerColorRgbCodesByColor } from '@webapp/components/survey/SurveyForm/nodeDefs/nodeDefUIProps'
+
+import { State } from './store'
+
+const headerColorItems = ({ i18n }) =>
+ toButtonGroupItems({
+ i18n,
+ object: FormHeaderColor,
+ labelPrefix: 'nodeDefEdit.formHeaderProps.headerColor.',
+ icon: ({ key }) => (
+
+ ),
+ })
+
+const FormHeaderProps = (props) => {
+ const { state, Actions } = props
+
+ const i18n = useI18n()
+
+ const nodeDef = State.getNodeDef(state)
+
+ const headerColor = NodeDef.getHeaderColor(nodeDef)
+
+ const onHeaderColorChange = useCallback(
+ (value) => {
+ Actions.setProp({ state, key: NodeDef.propKeys.headerColor, value: FormHeaderColor[value] })
+ },
+ [Actions, state]
+ )
+
+ return (
+
+
+
+ )
+}
+
+FormHeaderProps.propTypes = {
+ state: PropTypes.object.isRequired,
+ Actions: PropTypes.object.isRequired,
+}
+
+export default FormHeaderProps
diff --git a/webapp/components/survey/NodeDefDetails/FormHeaderProps.scss b/webapp/components/survey/NodeDefDetails/FormHeaderProps.scss
new file mode 100644
index 0000000000..c77d674582
--- /dev/null
+++ b/webapp/components/survey/NodeDefDetails/FormHeaderProps.scss
@@ -0,0 +1,11 @@
+.btn-group.form-header-color-btn-group {
+ button {
+ display: flex;
+ gap: 1rem;
+
+ .form-header-color-icon {
+ height: 1rem;
+ width: 1rem;
+ }
+ }
+}
diff --git a/webapp/components/survey/NodeDefDetails/NodeDefDetails.js b/webapp/components/survey/NodeDefDetails/NodeDefDetails.js
index a67ddf65e4..adad293ec4 100644
--- a/webapp/components/survey/NodeDefDetails/NodeDefDetails.js
+++ b/webapp/components/survey/NodeDefDetails/NodeDefDetails.js
@@ -53,12 +53,12 @@ const NodeDefDetails = () => {
}
/>
- {nodeDefType} {NodeDefUIProps.getIconByType(nodeDefType)}
+ {i18n.t(`surveyForm.addChildToTypes.${nodeDefType}`)} {NodeDefUIProps.getIconByType(nodeDefType)}
- Object.keys(NodeDef.textInputTypes).map((key) => ({
- key,
- label: i18n.t(`nodeDefEdit.textProps.textInputTypes.${key}`),
- }))
+ toButtonGroupItems({ i18n, object: NodeDef.textInputTypes, labelPrefix: 'nodeDefEdit.textProps.textInputTypes.' })
const textTransformTypes = ({ i18n }) =>
- Object.keys(NodeDef.textTransformValues).map((labelKey) => ({
- key: labelKey,
- label: i18n.t(`nodeDefEdit.textProps.textTransformTypes.${labelKey}`),
- }))
+ toButtonGroupItems({
+ i18n,
+ object: NodeDef.textTransformValues,
+ labelPrefix: 'nodeDefEdit.textProps.textTransformTypes.',
+ })
const TextProps = (props) => {
const { state, Actions } = props
@@ -30,25 +26,19 @@ const TextProps = (props) => {
const nodeDef = State.getNodeDef(state)
- const selectLabelValue = useCallback(
+ const onLabelValueChange = useCallback(
(value) => {
Actions.setProp({ state, key: NodeDef.propKeys.textTransform, value })
},
- [state]
+ [Actions, state]
)
- useEffect(() => {
- if (A.isEmpty(NodeDef.getTextTransform(nodeDef))) {
- selectLabelValue(NodeDef.textTransformValues.none)
- }
- }, [])
-
return (
<>
diff --git a/webapp/components/survey/SurveyForm/components/addNodeDefPanel.js b/webapp/components/survey/SurveyForm/components/addNodeDefPanel.js
index cf6e717dd6..ec8137515d 100644
--- a/webapp/components/survey/SurveyForm/components/addNodeDefPanel.js
+++ b/webapp/components/survey/SurveyForm/components/addNodeDefPanel.js
@@ -2,7 +2,6 @@ import './addNodeDefPanel.scss'
import React from 'react'
import { connect } from 'react-redux'
-import * as R from 'ramda'
import { useNavigate } from 'react-router'
import { useI18n } from '@webapp/store/system'
@@ -22,7 +21,7 @@ const AddNodeDefButtons = (props) => {
return (
<>
- {R.values(NodeDef.nodeDefType).map((type) => {
+ {Object.values(NodeDef.nodeDefType).map((type) => {
const nodeDefProps = NodeDefUIProps.getDefaultPropsByType(type, surveyCycleKey)
// Cannot add entities when entity is rendered as table
diff --git a/webapp/components/survey/SurveyForm/components/addNodeDefPanel.scss b/webapp/components/survey/SurveyForm/components/addNodeDefPanel.scss
index 03177e9658..93c2a0fe19 100644
--- a/webapp/components/survey/SurveyForm/components/addNodeDefPanel.scss
+++ b/webapp/components/survey/SurveyForm/components/addNodeDefPanel.scss
@@ -25,7 +25,8 @@
background-color: rgba($green, 0.85);
}
- &.entity {
+ &.entity,
+ &.formHeader {
margin-top: 0.7rem;
}
}
diff --git a/webapp/components/survey/SurveyForm/nodeDefs/components/NodeDefFormItem/NodeDefFormItem.js b/webapp/components/survey/SurveyForm/nodeDefs/components/NodeDefFormItem/NodeDefFormItem.js
index 181d613aa4..15e538708d 100644
--- a/webapp/components/survey/SurveyForm/nodeDefs/components/NodeDefFormItem/NodeDefFormItem.js
+++ b/webapp/components/survey/SurveyForm/nodeDefs/components/NodeDefFormItem/NodeDefFormItem.js
@@ -12,7 +12,7 @@ const NodeDefFormItem = (props) => {
const { edit, entry, label, lang, nodeDef, nodes, parentNode } = props
const nodeDefComponent = React.createElement(NodeDefUiProps.getComponent(nodeDef), { ...props })
- if (NodeDef.isEntity(nodeDef)) {
+ if (NodeDef.isEntity(nodeDef) || NodeDef.isFormHeader(nodeDef)) {
return nodeDefComponent
}
diff --git a/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefEntitySwitch.js b/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefEntitySwitch.js
index 81d2f3d385..6ab7bfd49d 100644
--- a/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefEntitySwitch.js
+++ b/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefEntitySwitch.js
@@ -27,8 +27,11 @@ const NodeDefEntitySwitch = (props) => {
return null
}
- const includeAnalysis = false
- const childDefs = Survey.getNodeDefChildrenSorted({ nodeDef, includeAnalysis, cycle: surveyCycleKey })(survey)
+ const childDefs = Survey.getNodeDefChildrenSorted({
+ nodeDef,
+ cycle: surveyCycleKey,
+ includeLayoutElements: true,
+ })(survey)
const nodeDefName = NodeDef.getName(nodeDef)
const childUuids = NodeDefLayout.getLayoutChildrenUuids(surveyCycleKey)(nodeDef)
diff --git a/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefFormHeader.js b/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefFormHeader.js
new file mode 100644
index 0000000000..9dc68b1863
--- /dev/null
+++ b/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefFormHeader.js
@@ -0,0 +1,31 @@
+import './nodeDefFormHeader.scss'
+
+import React from 'react'
+import PropTypes from 'prop-types'
+
+import * as NodeDef from '@core/survey/nodeDef'
+
+import Markdown from '@webapp/components/markdown'
+import * as NodeDefUIProps from '@webapp/components/survey/SurveyForm/nodeDefs/nodeDefUIProps'
+
+import { useSurveyPreferredLang } from '@webapp/store/survey'
+
+const NodeDefFormHeader = (props) => {
+ const { nodeDef } = props
+
+ const lang = useSurveyPreferredLang()
+
+ const backgroundColor = NodeDefUIProps.headerColorRgbCodesByColor[NodeDef.getHeaderColor(nodeDef)]
+
+ return (
+
+
+
+ )
+}
+
+NodeDefFormHeader.propTypes = {
+ nodeDef: PropTypes.object.isRequired,
+}
+
+export default NodeDefFormHeader
diff --git a/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefFormHeader.scss b/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefFormHeader.scss
new file mode 100644
index 0000000000..110719f8e5
--- /dev/null
+++ b/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefFormHeader.scss
@@ -0,0 +1,10 @@
+@import '../../../SurveyFormVars';
+
+.survey-form__node-def-form-header {
+ border: $formBorder;
+ padding: 0.3rem;
+ display: flex;
+ align-items: center;
+ font-size: 1.1rem;
+ font-weight: bold;
+}
diff --git a/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefText.js b/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefText.js
index da93458169..c5250ebe01 100644
--- a/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefText.js
+++ b/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefText.js
@@ -3,12 +3,12 @@ import './nodeDefText.scss'
import React from 'react'
import classNames from 'classnames'
-import { Input } from '@webapp/components/form/Input'
-import * as NodeDefUIProps from '@webapp/components/survey/SurveyForm/nodeDefs/nodeDefUIProps'
-
import * as NodeDef from '@core/survey/nodeDef'
import * as Node from '@core/record/node'
+import { Input } from '@webapp/components/form/Input'
+import * as NodeDefUIProps from '@webapp/components/survey/SurveyForm/nodeDefs/nodeDefUIProps'
+
import NodeDefErrorBadge from '../nodeDefErrorBadge'
import NodeDeleteButton from '../nodeDeleteButton'
@@ -59,13 +59,13 @@ const MultipleTextInput = (props) => {
const NodeDefText = (props) => {
const { edit, entryDataQuery, nodeDef, nodes } = props
- return edit ? (
-
- ) : NodeDef.isMultiple(nodeDef) && !entryDataQuery ? (
-
- ) : (
-
- )
+ if (edit) {
+ return
+ }
+ if (NodeDef.isMultiple(nodeDef) && !entryDataQuery) {
+ return
+ }
+ return
}
export default NodeDefText
diff --git a/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefText.scss b/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefText.scss
index 2dded45c10..641eaacfdc 100644
--- a/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefText.scss
+++ b/webapp/components/survey/SurveyForm/nodeDefs/components/types/nodeDefText.scss
@@ -39,3 +39,10 @@
background-color: $blueLightFocus;
}
}
+
+.survey-form__node-def-header {
+ border: $formBorder;
+ padding: 0.3rem;
+ display: flex;
+ align-items: center;
+}
diff --git a/webapp/components/survey/SurveyForm/nodeDefs/nodeDefUIProps.js b/webapp/components/survey/SurveyForm/nodeDefs/nodeDefUIProps.js
index 6e58496786..3f9c8afd6c 100644
--- a/webapp/components/survey/SurveyForm/nodeDefs/nodeDefUIProps.js
+++ b/webapp/components/survey/SurveyForm/nodeDefs/nodeDefUIProps.js
@@ -1,23 +1,35 @@
import React from 'react'
import * as R from 'ramda'
+import { FormHeaderColor } from '@openforis/arena-core'
+
import * as NodeDef from '@core/survey/nodeDef'
import * as NodeDefLayout from '@core/survey/nodeDefLayout'
import { valuePropsCoordinate, valuePropsTaxon } from '@core/survey/nodeValueProps'
import { NumberFormats } from '@webapp/components/form/Input'
+import NodeDefBoolean from './components/types/nodeDefBoolean'
+import NodeDefCode from './components/types/NodeDefCode'
+import NodeDefCoordinate from './components/types/nodeDefCoordinate'
+import NodeDefDate from './components/types/nodeDefDate'
import NodeDefEntitySwitch from './components/types/nodeDefEntitySwitch'
import NodeDefFile from './components/types/nodeDefFile'
+import NodeDefFormHeader from './components/types/nodeDefFormHeader'
import NodeDefTaxon from './components/types/nodeDefTaxon'
-import NodeDefCoordinate from './components/types/nodeDefCoordinate'
-import NodeDefCode from './components/types/NodeDefCode'
-import NodeDefBoolean from './components/types/nodeDefBoolean'
import NodeDefText from './components/types/nodeDefText'
-import NodeDefDate from './components/types/nodeDefDate'
import NodeDefTime from './components/types/nodeDefTime'
-const { integer, decimal, text, date, time, boolean, code, coordinate, taxon, file, entity } = NodeDef.nodeDefType
+const { integer, decimal, text, date, time, boolean, code, coordinate, taxon, file, entity, formHeader } =
+ NodeDef.nodeDefType
+
+export const headerColorRgbCodesByColor = {
+ [FormHeaderColor.blue]: '#b3e5fc',
+ [FormHeaderColor.green]: '#b2dfdb',
+ [FormHeaderColor.orange]: '#ffb38a',
+ [FormHeaderColor.red]: '#f97c7c',
+ [FormHeaderColor.yellow]: '#fffdaf',
+}
const propsUI = {
[integer]: {
@@ -121,6 +133,14 @@ const propsUI = {
[NodeDefLayout.keys.layout]: NodeDefLayout.newLayout(cycle, NodeDefLayout.renderType.table),
}),
},
+
+ [formHeader]: {
+ component: NodeDefFormHeader,
+ icon: ,
+ defaultProps: () => ({
+ [NodeDef.propKeys.headerColor]: FormHeaderColor.blue,
+ }),
+ },
}
const getPropByType =
diff --git a/webapp/views/App/Header/Header.js b/webapp/views/App/Header/Header.js
index 0f6506849a..5f9164e2b6 100644
--- a/webapp/views/App/Header/Header.js
+++ b/webapp/views/App/Header/Header.js
@@ -51,8 +51,8 @@ const Header = () => {
const surveyTitle = surveyLabel ? `${surveyLabel} [${surveyName}]` : surveyName
return (
-
-
+
+
@@ -60,7 +60,7 @@ const Header = () => {
-
+
{Survey.isValid(surveyInfo) && (
<>
{
to={appModuleUri(homeModules.surveyInfo)}
className="btn-s btn-transparent"
>
-
+
{
/>
{canEditSurvey && Survey.isDraft(surveyInfo) && }
- {appSaving && }
+ {appSaving && }
>
)}
@@ -89,7 +89,7 @@ const Header = () => {