diff --git a/.vscode/settings.json b/.vscode/settings.json
index 662beba..dff3352 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -2,6 +2,7 @@
"cSpell.words": [
"EPSG",
"NCCRD",
+ "REIPPP",
"STAs",
"cdmes",
"cdmm",
diff --git a/src/api/src/graphql/schema/type-defs/adaptation.graphql b/src/api/src/graphql/schema/type-defs/adaptation.graphql
index 022ff51..d95dce2 100644
--- a/src/api/src/graphql/schema/type-defs/adaptation.graphql
+++ b/src/api/src/graphql/schema/type-defs/adaptation.graphql
@@ -4,16 +4,16 @@ input AdaptationInput {
# Sector description :: Please describe the sector
otherAdaptationSector: String
# National policy :: Indicate the national policy or strategy that the measure is responding to :: adaptationPolicies
- nationalPolicy: ControlledVocabularyInput
+ nationalPolicy: [ControlledVocabularyInput]
# National policy description :: Please describe the policy
otherNationalPolicy: String
# Provincial or Municipal policy :: Indicate the provincial or municipal policy or strategy that the measure is responding to :: adaptationPolicies
- regionalPolicy: ControlledVocabularyInput
+ regionalPolicy: [ControlledVocabularyInput]
# Regional policy description :: Please describe the policy
otherRegionalPolicy: String
# Indicate the corresponding intervention, goal, or target :: Please select an appropriate value based on your other form inputs above :: adaptationPolicies
- target: ControlledVocabularyInput
- # Other corresponding intervention, goal, or target :: Please describe based on your other form inputs above
+ target: [ControlledVocabularyInput]
+ # Other corresponding intervention(s), goal(s), or target(s) :: Please describe based on your other form inputs above
otherTarget: String
# Hazard :: Select hazard :: hazards
diff --git a/src/api/src/graphql/schema/type-defs/mitigation.graphql b/src/api/src/graphql/schema/type-defs/mitigation.graphql
index 1aa6648..d7a4242 100644
--- a/src/api/src/graphql/schema/type-defs/mitigation.graphql
+++ b/src/api/src/graphql/schema/type-defs/mitigation.graphql
@@ -14,12 +14,12 @@ input MitigationInput {
# Select the mitigation program the project is linked to :: A programme is a high level support measure that support mitigation actions/project types above e.g 1A1 REIPPP :: mitigationProgramme
mitigationProgramme: ControlledVocabularyInput
# National policy :: Indicate the national policy or strategy that the measure is responding to :: mitigationPolicies
- nationalPolicy: ControlledVocabularyInput
- # National policy description :: Please describe the policy
+ nationalPolicy: [ControlledVocabularyInput]
+ # (Other) national policy(ies) description :: Please describe the policy(ies)
otherNationalPolicy: String
# Provincial or Municipal policy :: Indicate the provincial or municipal policy or strategy that the measure is responding to :: mitigationPolicies
- regionalPolicy: ControlledVocabularyInput
- # Regional policy description :: Please describe the policy
+ regionalPolicy: [ControlledVocabularyInput]
+ # (Other) regional policy(ies) description :: Please describe the policy(ies)
otherRegionalPolicy: String
# Primary intended outcome :: Primary intended outcome (Indicate the expected or achieved goals)
primaryIntendedOutcome: String
diff --git a/src/api/src/graphql/schema/type-defs/project.graphql b/src/api/src/graphql/schema/type-defs/project.graphql
index 9563266..2882eec 100644
--- a/src/api/src/graphql/schema/type-defs/project.graphql
+++ b/src/api/src/graphql/schema/type-defs/project.graphql
@@ -37,13 +37,13 @@ input ProjectInput {
# Estimated budget range :: If you don't know the actual budget, please provide a range estimate :: budgetRanges
estimatedBudget: ControlledVocabularyInput
# Indicate the type of measure :: Mitigation measures are defined as 'actions aimed at reducing the extent or likelihood of global climate change through the reduction or displacement of greenhouse gas emissions (GHGs) (e.g. through emission reduction, energy efficiency or renewable energy projects'.
Adaptation measures are defined as 'actions preventing or minimising the negative effects and taking advantage of positive effects of global warming in addition to actions which would have occurred naturally or as a matter of course.
Cross-cutting Measures that contain elements of both adaptation and mitigation :: interventionTypes
- interventionType: ControlledVocabularyInput!
+ interventionType: ControlledVocabularyInput
# Implementation status :: Operational - Ongoing project
Planned project - Project has not begun but is being constructed or has been registered/approved/funded
Complete - The project has been finalized
Discontinued - planned project terminated :: actionStatus
implementationStatus: ControlledVocabularyInput
# Type of funding :: Any financial resources that is spent on supporting either mitigation and adaption efforts in South Africa. Climate finance refers to domestic (drawn from local public or private organisations), International (bilateral or multilateral grants or loans). Bilateral funding describes money which is given directly from one government to another, whereas multilateral funding comes from numerous different governments and organisations and is usually arranged by an international organisation such as the World Bank or the UN :: fundingTypes
fundingType: ControlledVocabularyInput
# Province :: Select province(s) :: regions
- province: [ControlledVocabularyInput]
+ province: [ControlledVocabularyInput]!
# District municipality :: Select district municipality(s) :: regions
districtMunicipality: [ControlledVocabularyInput]
# Local municipality :: Select local municipality(s) :: regions
diff --git a/src/client/src/components/multiselect/index.jsx b/src/client/src/components/multiselect/index.jsx
index 3df1cd3..7dd0539 100644
--- a/src/client/src/components/multiselect/index.jsx
+++ b/src/client/src/components/multiselect/index.jsx
@@ -37,7 +37,7 @@ export default ({
const theme = useTheme()
return (
-
+
{selected.map(value => {
@@ -90,6 +91,7 @@ export default ({
key={value}
label={value}
style={{
+ maxWidth: '100%',
...style,
}}
{...props}
@@ -102,7 +104,7 @@ export default ({
{options.map(option => (
))}
{loading ? : null}
diff --git a/src/client/src/components/project-form/form/components/locations-picker/list-input.jsx b/src/client/src/components/project-form/form/components/locations-picker/list-input.jsx
index ff7da52..9da2f68 100644
--- a/src/client/src/components/project-form/form/components/locations-picker/list-input.jsx
+++ b/src/client/src/components/project-form/form/components/locations-picker/list-input.jsx
@@ -26,7 +26,7 @@ const NewPointForm = ({ closeFn, points, setPoints }) => {
onChange={e => setLat(e.target.value)}
label="Latitude"
type="number"
- helperText="Latitude in degrees"
+ helperText="Latitude in degrees (East / West)"
fullWidth
variant="outlined"
margin="normal"
@@ -36,7 +36,7 @@ const NewPointForm = ({ closeFn, points, setPoints }) => {
onChange={e => setLng(e.target.value)}
label="Longitude"
type="number"
- helperText="Longitude in degrees"
+ helperText="Longitude in degrees (North / South)"
fullWidth
variant="outlined"
margin="normal"
diff --git a/src/client/src/components/project-form/sections/adaptation-details/_render-field.jsx b/src/client/src/components/project-form/sections/adaptation-details/_render-field.jsx
index af61ea1..822c951 100644
--- a/src/client/src/components/project-form/sections/adaptation-details/_render-field.jsx
+++ b/src/client/src/components/project-form/sections/adaptation-details/_render-field.jsx
@@ -1,5 +1,9 @@
import { useContext, lazy, Suspense } from 'react'
-import { GqlBoundFormInput, ControlledVocabularySelect } from '../../form'
+import {
+ GqlBoundFormInput,
+ ControlledVocabularySelect,
+ ControlledVocabularySelectMultiple,
+} from '../../form'
import { context as formContext } from '../../context'
import Loading from '../../../loading'
@@ -22,9 +26,9 @@ export default ({ field, formName }) => {
useContext(formContext)
const { name: fieldName, description, type } = field
let [placeholder, helperText, tree] = description?.split('::').map(s => s.trim()) || []
- const { name: inputType } = type
- const isRequired = !inputType
- const value = form[fieldName]
+ const { kind } = type
+ const isRequired = kind === 'NON_NULL'
+ const value = form?.[fieldName] || undefined
if (helperText === '') {
helperText = ` `
@@ -49,36 +53,36 @@ export default ({ field, formName }) => {
*/
if (fieldName === 'nationalPolicy') {
return (
-
updateForm({ [fieldName]: val, target: undefined, otherTarget: undefined })
}
- placeholder={placeholder}
+ label={placeholder}
helperText={helperText}
/>
)
} else if (fieldName === 'otherNationalPolicy') {
- if (!form?.nationalPolicy?.term?.match(/^Other\s/)) {
+ if (!form?.nationalPolicy?.find(({ term }) => term?.match(/^Other\s/))) {
return null
}
} else if (fieldName === 'target') {
if (form.nationalPolicy) {
return (
- term)}
name={fieldName}
value={value}
error={isRequired && !value}
onChange={val => updateForm({ [fieldName]: val, otherTarget: undefined })}
- placeholder={placeholder}
+ label={placeholder}
helperText={helperText}
/>
)
@@ -86,27 +90,27 @@ export default ({ field, formName }) => {
return null
}
} else if (fieldName === 'otherTarget') {
- if (!form?.target || !form.target.term?.match(/^Other/)) {
+ if (!form?.target || !form.target?.find(({ term }) => term?.match(/^Other/))) {
return null
}
}
if (fieldName === 'regionalPolicy') {
return (
- updateForm({ [fieldName]: val, otherRegionalPolicy: undefined })}
- placeholder={placeholder}
+ label={placeholder}
helperText={helperText}
/>
)
} else if (fieldName === 'otherRegionalPolicy') {
- if (!form?.regionalPolicy?.term?.match(/^Other\s/)) {
+ if (!form?.regionalPolicy?.find(({ term }) => term?.match(/^Other\s/))) {
return null
}
}
diff --git a/src/client/src/components/project-form/sections/mitigation-details/_render-field.jsx b/src/client/src/components/project-form/sections/mitigation-details/_render-field.jsx
index 5ad5ac2..f93e3c3 100644
--- a/src/client/src/components/project-form/sections/mitigation-details/_render-field.jsx
+++ b/src/client/src/components/project-form/sections/mitigation-details/_render-field.jsx
@@ -1,6 +1,10 @@
import { useContext, lazy, Suspense } from 'react'
import Loading from '../../../loading'
-import { GqlBoundFormInput, ControlledVocabularySelect } from '../../form'
+import {
+ GqlBoundFormInput,
+ ControlledVocabularySelect,
+ ControlledVocabularySelectMultiple,
+} from '../../form'
import { context as formContext } from '../../context'
const EnergyCalculator = lazy(() => import('../../form/components/calculators/energy'))
@@ -35,9 +39,9 @@ export default ({ field, formName }) => {
useContext(formContext)
const { name: fieldName, description, type } = field
let [placeholder, helperText, tree] = description?.split('::').map(s => s.trim()) || []
- const { name: inputType } = type
- const isRequired = !inputType
- const value = form[fieldName]
+ const { kind } = type
+ const isRequired = kind === 'NON_NULL'
+ const value = form?.[fieldName] || undefined
if (helperText === '') {
helperText = ` `
@@ -193,20 +197,20 @@ export default ({ field, formName }) => {
*/
if (fieldName === 'nationalPolicy') {
return (
- updateForm({ [fieldName]: val, otherNationalPolicy: undefined })}
- placeholder={placeholder}
+ label={placeholder}
helperText={helperText}
/>
)
} else if (fieldName === 'otherNationalPolicy') {
- if (!form?.nationalPolicy?.term?.match(/^Other\s/)) {
+ if (!form?.nationalPolicy?.find(({ term }) => term?.match(/^Other\s/))) {
return null
}
}
@@ -216,20 +220,20 @@ export default ({ field, formName }) => {
*/
if (fieldName === 'regionalPolicy') {
return (
- updateForm({ [fieldName]: val, otherRegionalPolicy: undefined })}
- placeholder={placeholder}
+ label={placeholder}
helperText={helperText}
/>
)
} else if (fieldName === 'otherRegionalPolicy') {
- if (!form?.regionalPolicy?.term?.match(/^Other\s/)) {
+ if (!form?.regionalPolicy?.find(({ term }) => term?.match(/^Other\s/))) {
return null
}
}
@@ -311,7 +315,7 @@ export default ({ field, formName }) => {
}
if (carbonCreditsFields.includes(fieldName)) {
- if (!(form.carbonCredit || '').toBoolean()) {
+ if (!`'${form.carbonCredit}'`.toBoolean()) {
return null
}
}