diff --git a/locale/en.json b/locale/en.json index b723456e..14c0ca08 100644 --- a/locale/en.json +++ b/locale/en.json @@ -1286,5 +1286,6 @@ "MY_PENDING_SIGHTINGS" : "My pending sightings", "MY_SIGHTINGS" : "My sightings", "MY_UNAPPROVED_SIGHTINGS" : "My unapproved sightings", - "TotalAccount" : "Total Account: {totalAccount}" + "TotalAccount" : "Total Account: {totalAccount}", + "MANAGE_REGIONS" : "Manage Regions" } diff --git a/src/AuthenticatedSwitch.jsx b/src/AuthenticatedSwitch.jsx index 011532f5..8d0597b4 100644 --- a/src/AuthenticatedSwitch.jsx +++ b/src/AuthenticatedSwitch.jsx @@ -47,6 +47,7 @@ import Footer from './components/Footer'; import { defaultCrossfadeDuration } from './constants/defaults'; import Requests from './pages/setup/Requests'; import SpeciesManagement from './pages/fieldManagement/SpeciesManagement'; +import RegionManagement from './pages/fieldManagement/RegionManagement'; import ChangeLog from './pages/changeLog/ChangeLog'; import DataPage from './pages/dataPage/DataPage'; @@ -115,6 +116,9 @@ export default function AuthenticatedSwitch({ + + + @@ -231,4 +235,4 @@ export default function AuthenticatedSwitch({ /> ); -} +} \ No newline at end of file diff --git a/src/components/fields/edit/LocationIdEditor.jsx b/src/components/fields/edit/LocationIdEditor.jsx index e102665b..4e82d21b 100644 --- a/src/components/fields/edit/LocationIdEditor.jsx +++ b/src/components/fields/edit/LocationIdEditor.jsx @@ -90,8 +90,16 @@ export default function LocationIdEditor(props) { }); useEffect(() => { - const selectedLabel = Object.keys(nameToIdMap).find(name => nameToIdMap[name] === selected); - setSearchText(selectedLabel); + const selectedLabel = + Object.keys(nameToIdMap) + .find(name => nameToIdMap[name] === selected); + const selectedNode = flatternedTree[selected]; + if(!selectedNode){ + setSearchText(''); + return; + }else { + setSearchText(selectedLabel); + } }, [selected]); return ( @@ -111,10 +119,9 @@ export default function LocationIdEditor(props) { onChange={onChange} searchText={searchText} showData={showData} - setSearchText={setSearchText} - setModalOpen={setModalOpen} selected={selected} setSelected={setSelected} + flatternedTree={flatternedTree} />} {showDescription ? ( {description} @@ -123,4 +130,4 @@ export default function LocationIdEditor(props) { ) -} +} \ No newline at end of file diff --git a/src/components/fields/edit/TreeViewComponent.jsx b/src/components/fields/edit/TreeViewComponent.jsx index 0331ed4f..bebe94b6 100644 --- a/src/components/fields/edit/TreeViewComponent.jsx +++ b/src/components/fields/edit/TreeViewComponent.jsx @@ -33,11 +33,18 @@ const TreeViewComponent = (props) => { showData, selected, setSelected, + flatternedTree, } = props; const classes = useStyles(); const handleNodeSelect = (event, nodeId) => { + const node = flatternedTree[nodeId]; + if(node.placeholderOnly){ + onChange(""); + setSelected(""); + return; + } onChange(nodeId); setSelected(nodeId); }; @@ -53,7 +60,10 @@ const TreeViewComponent = (props) => { display: 'flex', alignItems: 'center', }}> - + {node.name} } @@ -86,4 +96,4 @@ const TreeViewComponent = (props) => { ); }; -export default TreeViewComponent; +export default TreeViewComponent; \ No newline at end of file diff --git a/src/pages/fieldManagement/RegionManagement.jsx b/src/pages/fieldManagement/RegionManagement.jsx new file mode 100644 index 00000000..9c3b3218 --- /dev/null +++ b/src/pages/fieldManagement/RegionManagement.jsx @@ -0,0 +1,128 @@ +import React, { useEffect, useState } from 'react'; +import { get } from 'lodash-es'; +import { FormattedMessage } from 'react-intl'; +import { useHistory } from 'react-router-dom'; +import MainColumn from '../../components/MainColumn'; +import TreeEditor from './settings/defaultFieldComponents/TreeEditor'; +import useSiteSettings from '../../models/site/useSiteSettings'; +import Button from '../../components/Button'; +import Text from '../../components/Text'; +import SettingsBreadcrumbs from '../../components/SettingsBreadcrumbs'; +import usePutSiteSetting from '../../models/site/usePutSiteSetting'; +import CustomAlert from '../../components/Alert'; + +function getInitialFormState(siteSettings) { + const regions = get( + siteSettings, + ['site.custom.regions', 'value'], + [], + ); + const species = get(siteSettings, ['site.species', 'value'], []); + const relationships = get( + siteSettings, + ['relationship_type_roles', 'value'], + [], + ); + const socialGroups = get( + siteSettings, + ['social_group_roles', 'value'], + [], + ); + + return { regions, species, relationships, socialGroups }; +} + +export default function RegionManagement() { + const [formSettings, setFormSettings] = useState(null); + const { data: siteSettings } = useSiteSettings(); + const history = useHistory(); + + const { + mutate: putSiteSetting, + error: putError, + loading, + clearError, + } = usePutSiteSetting(); + + const onClose = () => { + clearError(); + history.push('/settings/fields'); + }; + + useEffect( + () => setFormSettings(getInitialFormState(siteSettings)), + [siteSettings], + ); + + const tree = get(formSettings, ['regions', 'locationID'], []); + + return ( + + + + { + const newRegions = { + ...get(formSettings, 'regions', {}), + locationID, + }; + setFormSettings({ + ...formSettings, + regions: newRegions, + }); + }} + /> +
+ + +
+
+ {putError ? ( + + ) : null} +
+
+ ); +} \ No newline at end of file diff --git a/src/pages/fieldManagement/settings/DefaultFieldTable.jsx b/src/pages/fieldManagement/settings/DefaultFieldTable.jsx index fa0ae1fd..465a520e 100644 --- a/src/pages/fieldManagement/settings/DefaultFieldTable.jsx +++ b/src/pages/fieldManagement/settings/DefaultFieldTable.jsx @@ -11,7 +11,7 @@ import DataDisplay from '../../../components/dataDisplays/DataDisplay'; import ActionIcon from '../../../components/ActionIcon'; import Text from '../../../components/Text'; import categoryTypes from '../../../constants/categoryTypes'; -import { RegionEditor } from './defaultFieldComponents/Editors'; +// import { RegionEditor } from './defaultFieldComponents/Editors'; import RelationshipEditor from './defaultFieldComponents/RelationshipEditor'; import SocialGroupsEditor from './defaultFieldComponents/SocialGroupsEditor'; import { cellRendererTypes } from '../../../components/dataDisplays/cellRenderers'; @@ -22,14 +22,13 @@ const configurableFields = [ backendPath: 'site.species', labelId: 'SPECIES', type: categoryTypes.sighting, - // Editor: SpeciesEditor, }, { id: 'region', backendPath: 'site.custom.regions', labelId: 'REGION', type: categoryTypes.sighting, - Editor: RegionEditor, + // Editor: RegionEditor, }, { id: 'relationship', @@ -84,14 +83,49 @@ export default function DefaultFieldTable({ siteSettings }) { [siteSettings], ); + const onCloseEditor = () => { + clearError(); + setEditField(null); + }; + + const onClose = () => { + setFormSettings(getInitialFormState(siteSettings)); + onCloseEditor(); + }; + + const onSubmit = async () => { + if (editField?.id === 'region') { + console.log('formSettings.regions', formSettings.regions); + const response = await putSiteSetting({ + property: editField.backendPath, + data: formSettings.regions, + }); + if (response?.status === 200) onCloseEditor(); + } + if (editField?.id === 'relationship') { + const response = await putSiteSetting({ + property: editField.backendPath, + data: formSettings.relationships, + }); + if (response?.status === 200) onCloseEditor(); + } + if (editField?.id === 'socialGroups') { + const response = await putSiteSetting({ + property: editField.backendPath, + data: formSettings.socialGroups, + }); + if (response?.status === 200) onCloseEditor(); + } + }; + const tableColumns = [ { name: 'labelId', label: intl.formatMessage({ id: 'LABEL' }), options: { - customBodyRender: labelId => ( - - ), + customBodyRender: ( + labelId, //eslint-disable-line + ) => , }, }, { @@ -103,15 +137,20 @@ export default function DefaultFieldTable({ siteSettings }) { name: 'actions', label: intl.formatMessage({ id: 'ACTIONS' }), options: { - customBodyRender: (_, field) => ( + customBodyRender: ( + _, + field, //eslint-disable-line + ) => ( { - if(field.id === 'species'){ + if (field.id === 'species') { history.push('/settings/fields/species'); - }else { + } else if (field.id === 'region') { + history.push('/settings/fields/regions'); + } else { setEditField(field); - } + } }} /> ), @@ -119,11 +158,6 @@ export default function DefaultFieldTable({ siteSettings }) { }, ]; - const onCloseEditor = () => { - clearError(); - setEditField(null); - }; - return ( {editField && ( @@ -131,33 +165,8 @@ export default function DefaultFieldTable({ siteSettings }) { siteSettings={siteSettings} formSettings={formSettings} setFormSettings={setFormSettings} - onClose={() => { - setFormSettings(getInitialFormState(siteSettings)); - onCloseEditor(); - }} - onSubmit={async () => { - if (editField?.id === 'region') { - const response = await putSiteSetting({ - property: editField.backendPath, - data: formSettings.regions, - }); - if (response?.status === 200) onCloseEditor(); - } - if (editField?.id === 'relationship') { - const response = await putSiteSetting({ - property: editField.backendPath, - data: formSettings.relationships, - }); - if (response?.status === 200) onCloseEditor(); - } - if (editField?.id === 'socialGroups') { - const response = await putSiteSetting({ - property: editField.backendPath, - data: formSettings.socialGroups, - }); - if (response?.status === 200) onCloseEditor(); - } - }} + onClose={onClose} + onSubmit={onSubmit} > {error ? ( { const newLocationID = leaf.locationID - ? updateTree(leaf.locationID, leafId, newLeafName) + ? updateTree( + leaf.locationID, + leafId, + newLeafName, + placeholderOnly, + ) : undefined; - const newLeaf = { ...leaf, locationID: newLocationID }; - if (newLeaf.id === leafId) newLeaf.name = newLeafName; + const newLeaf = { + ...leaf, + locationID: newLocationID, + }; + if (newLeaf.id === leafId) { + newLeaf.name = newLeafName; + newLeaf.placeholderOnly = placeholderOnly; + } return newLeaf; }); } const Leaf = function ({ level, data, root, onChange, children }) { + const [placeholderOnly, setPlaceholderOnly] = useState( + data.placeholderOnly || false, + ); return (
{ - onChange(updateTree(root, data.id, newName)); + onChange( + updateTree(root, data.id, newName, placeholderOnly), + ); }} value={get(data, 'name')} - autoFocus + // autoFocus InputProps={{ endAdornment: ( { onChange(addLeaf(root, data.id)); }} > - + { onChange(deleteFromTree(root, data.id)); }} /> ), + startAdornment: ( + + { + const newPlaceholderOnly = !placeholderOnly; + setPlaceholderOnly(newPlaceholderOnly); + onChange( + updateTree( + root, + data.id, + data.name, + newPlaceholderOnly, + ), + ); + }} + name="startCheckbox" + color="primary" + /> + } + /> + + ), }} /> {children} @@ -127,17 +171,18 @@ export default function TreeEditor({
- @@ -153,4 +198,4 @@ export default function TreeEditor({
); -} +} \ No newline at end of file