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

Add merge buttons to the show pages for mergeable objects #4856

Merged
merged 3 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions client/src/components/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,14 @@ export default class Model {
return Model.filterClientSideFields(this, ...additionalFields)
}

fixupFields() {
if (this.customFields) {
this[DEFAULT_CUSTOM_FIELDS_PARENT] = utils.parseJsonSafe(
this.customFields
)
}
}

static isAuthorized(user, customSensitiveInformationField) {
// Admins are always allowed
if (user?.isAdmin()) {
Expand Down
5 changes: 5 additions & 0 deletions client/src/models/Location.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,4 +308,9 @@ export default class Location extends Model {
filterClientSideFields(...additionalFields) {
return Location.filterClientSideFields(this, ...additionalFields)
}

fixupFields() {
super.fixupFields()
this.displayedCoordinate = convertLatLngToMGRS(this.lat, this.lng)
}
}
9 changes: 9 additions & 0 deletions client/src/models/Person.js
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,15 @@ export default class Person extends Model {
return Person.filterClientSideFields(this, ...additionalFields)
}

fixupFields() {
super.fixupFields()
if (this.customSensitiveInformation) {
this[SENSITIVE_CUSTOM_FIELDS_PARENT] = utils.parseSensitiveFields(
this.customSensitiveInformation
)
}
}

static isAuthorized(user, customSensitiveInformationField, position) {
if (Model.isAuthorized(user, customSensitiveInformationField)) {
return true
Expand Down
41 changes: 27 additions & 14 deletions client/src/pages/admin/merge/MergeLocations.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,17 @@ import PropTypes from "prop-types"
import React, { useEffect, useState } from "react"
import { Button, Col, Container, Form, Row } from "react-bootstrap"
import { connect } from "react-redux"
import { useNavigate } from "react-router-dom"
import { useLocation, useNavigate } from "react-router-dom"
import LOCATIONS_ICON from "resources/locations.png"
import Settings from "settings"
import utils from "utils"

const GQL_GET_LOCATION = gql`
query ($uuid: String!) {
location(uuid: $uuid) {
${Location.allFieldsQuery}
}
}
`

const GQL_MERGE_LOCATION = gql`
mutation ($loserUuid: String!, $winnerLocation: LocationInput!) {
Expand All @@ -53,6 +60,8 @@ const GQL_MERGE_LOCATION = gql`

const MergeLocations = ({ pageDispatchers }) => {
const navigate = useNavigate()
const { state } = useLocation()
const initialLeftUuid = state?.initialLeftUuid
const [saveError, setSaveError] = useState(null)
const [saveWarning, setSaveWarning] = useState(null)
const [locationFormat, setLocationFormat] = useState(Location.locationFormat)
Expand All @@ -68,6 +77,15 @@ const MergeLocations = ({ pageDispatchers }) => {
})
usePageTitle("Merge Locations")

if (!mergeState[MERGE_SIDES.LEFT] && initialLeftUuid) {
API.query(GQL_GET_LOCATION, {
uuid: initialLeftUuid
}).then(data => {
const location = new Location(data.location)
location.fixupFields()
dispatchMergeActions(setMergeable(location, MERGE_SIDES.LEFT))
})
}
const location1 = mergeState[MERGE_SIDES.LEFT]
const location2 = mergeState[MERGE_SIDES.RIGHT]
const mergedLocation = mergeState.merged
Expand Down Expand Up @@ -101,6 +119,7 @@ const MergeLocations = ({ pageDispatchers }) => {
locationFormat={locationFormat}
setLocationFormat={setLocationFormat}
locationFormatLabel={locationFormatLabel}
disabled={!!initialLeftUuid}
/>
</Col>
<Col md={4} id="mid-merge-loc-col">
Expand Down Expand Up @@ -368,6 +387,7 @@ function getLocationFilters() {
const LocationColumn = ({
align,
label,
disabled,
mergeState,
dispatchMergeActions,
locationFormat,
Expand All @@ -392,24 +412,16 @@ const LocationColumn = ({
overlayRenderRow={LocationOverlayRow}
filterDefs={getLocationFilters()}
onChange={value => {
if (value?.customFields) {
value[DEFAULT_CUSTOM_FIELDS_PARENT] = utils.parseJsonSafe(
value.customFields
)
}
if (value) {
value.displayedCoordinate = convertLatLngToMGRS(
value.lat,
value.lng
)
}
value?.fixupFields()
dispatchMergeActions(setMergeable(value, align))
}}
objectType={Location}
valueKey="name"
fields={Location.allFieldsQuery}
addon={LOCATIONS_ICON}
vertical
disabled={disabled}
showRemoveButton={!disabled}
/>
</ColTitle>
{areAllSet(location) && (
Expand Down Expand Up @@ -603,7 +615,7 @@ const LocationColumn = ({
Object.entries(Settings.fields.location.customFields).map(
([fieldName, fieldConfig]) => {
const fieldValue =
location[DEFAULT_CUSTOM_FIELDS_PARENT][fieldName]
location?.[DEFAULT_CUSTOM_FIELDS_PARENT]?.[fieldName]
return (
<MergeField
key={fieldName}
Expand Down Expand Up @@ -636,6 +648,7 @@ const LocationColumn = ({
LocationColumn.propTypes = {
align: PropTypes.oneOf(["left", "right"]).isRequired,
label: PropTypes.string.isRequired,
disabled: PropTypes.bool,
mergeState: PropTypes.object,
dispatchMergeActions: PropTypes.func,
locationFormat: PropTypes.oneOf(Object.keys(Location.LOCATION_FORMATS))
Expand Down
35 changes: 27 additions & 8 deletions client/src/pages/admin/merge/MergeOrganizations.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,19 @@ import PropTypes from "prop-types"
import React, { useState } from "react"
import { Button, Col, Container, Form, Row } from "react-bootstrap"
import { connect } from "react-redux"
import { useNavigate } from "react-router-dom"
import { useLocation, useNavigate } from "react-router-dom"
import ORGANIZATIONS_ICON from "resources/organizations.png"
import Settings from "settings"
import utils from "utils"

const GQL_GET_ORGANIZATION = gql`
query ($uuid: String!) {
organization(uuid: $uuid) {
${Organization.allFieldsQuery}
}
}
`

const GQL_MERGE_ORGANIZATION = gql`
mutation ($loserUuid: String!, $winnerOrganization: OrganizationInput!) {
mergeOrganizations(
Expand All @@ -57,6 +65,8 @@ const GQL_MERGE_ORGANIZATION = gql`

const MergeOrganizations = ({ pageDispatchers }) => {
const navigate = useNavigate()
const { state } = useLocation()
const initialLeftUuid = state?.initialLeftUuid
const [saveError, setSaveError] = useState(null)
const [mergeState, dispatchMergeActions] = useMergeObjects(
MODEL_TO_OBJECT_TYPE.Organization
Expand All @@ -69,6 +79,15 @@ const MergeOrganizations = ({ pageDispatchers }) => {
})
usePageTitle("Merge Organizations")

if (!mergeState[MERGE_SIDES.LEFT] && initialLeftUuid) {
API.query(GQL_GET_ORGANIZATION, {
uuid: initialLeftUuid
}).then(data => {
const organization = new Organization(data.organization)
organization.fixupFields()
dispatchMergeActions(setMergeable(organization, MERGE_SIDES.LEFT))
})
}
const organization1 = mergeState[MERGE_SIDES.LEFT]
const organization2 = mergeState[MERGE_SIDES.RIGHT]
const mergedOrganization = mergeState.merged
Expand All @@ -89,6 +108,7 @@ const MergeOrganizations = ({ pageDispatchers }) => {
dispatchMergeActions={dispatchMergeActions}
align={ALIGN_OPTIONS.LEFT}
label="Organization 1"
disabled={!!initialLeftUuid}
/>
</Col>
<Col md={4} id="mid-merge-org-col">
Expand Down Expand Up @@ -437,6 +457,7 @@ const organizationsFilters = {
const OrganizationColumn = ({
align,
label,
disabled,
mergeState,
dispatchMergeActions
}) => {
Expand All @@ -461,19 +482,16 @@ const OrganizationColumn = ({
overlayRenderRow={OrganizationSimpleOverlayRow}
filterDefs={organizationsFilters}
onChange={value => {
const newValue = value
if (newValue?.customFields) {
newValue[DEFAULT_CUSTOM_FIELDS_PARENT] = utils.parseJsonSafe(
value.customFields
)
}
value?.fixupFields()
dispatchMergeActions(setMergeable(value, align))
}}
objectType={Organization}
valueKey="shortName"
fields={Organization.allFieldsQuery}
addon={ORGANIZATIONS_ICON}
vertical
disabled={disabled}
showRemoveButton={!disabled}
/>
</ColTitle>
{areAllSet(organization) && (
Expand Down Expand Up @@ -802,7 +820,7 @@ const OrganizationColumn = ({
Object.entries(Settings.fields.organization.customFields).map(
([fieldName, fieldConfig]) => {
const fieldValue =
organization[DEFAULT_CUSTOM_FIELDS_PARENT][fieldName]
organization?.[DEFAULT_CUSTOM_FIELDS_PARENT]?.[fieldName]
return (
<MergeField
key={fieldName}
Expand Down Expand Up @@ -842,6 +860,7 @@ const OrganizationCol = styled.div`
OrganizationColumn.propTypes = {
align: PropTypes.oneOf(["left", "right"]).isRequired,
label: PropTypes.string.isRequired,
disabled: PropTypes.bool,
mergeState: PropTypes.object,
dispatchMergeActions: PropTypes.func
}
Expand Down
48 changes: 34 additions & 14 deletions client/src/pages/admin/merge/MergePeople.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,19 @@ import PropTypes from "prop-types"
import React, { useState } from "react"
import { Button, Col, Container, Form, Row } from "react-bootstrap"
import { connect } from "react-redux"
import { useNavigate } from "react-router-dom"
import { useLocation, useNavigate } from "react-router-dom"
import PEOPLE_ICON from "resources/people.png"
import Settings from "settings"
import utils from "utils"

const GQL_GET_PERSON = gql`
query($uuid: String!) {
person(uuid: $uuid) {
${Person.allFieldsQuery}
}
}
`

const GQL_MERGE_PERSON = gql`
mutation ($loserUuid: String!, $winnerPerson: PersonInput!) {
mergePeople(loserUuid: $loserUuid, winnerPerson: $winnerPerson)
Expand All @@ -58,6 +66,8 @@ const GQL_MERGE_PERSON = gql`

const MergePeople = ({ pageDispatchers }) => {
const navigate = useNavigate()
const { state } = useLocation()
const initialLeftUuid = state?.initialLeftUuid
const [saveError, setSaveError] = useState(null)
const [showHistoryModal, setShowHistoryModal] = useState(false)
const [mergeState, dispatchMergeActions] = useMergeObjects(
Expand All @@ -71,6 +81,15 @@ const MergePeople = ({ pageDispatchers }) => {
})
usePageTitle("Merge People")

if (!mergeState[MERGE_SIDES.LEFT] && initialLeftUuid) {
API.query(GQL_GET_PERSON, {
uuid: initialLeftUuid
}).then(data => {
const person = new Person(data.person)
person.fixupFields()
dispatchMergeActions(setMergeable(person, MERGE_SIDES.LEFT))
})
}
const person1 = mergeState[MERGE_SIDES.LEFT]
const person2 = mergeState[MERGE_SIDES.RIGHT]
const mergedPerson = mergeState.merged
Expand All @@ -88,6 +107,7 @@ const MergePeople = ({ pageDispatchers }) => {
dispatchMergeActions={dispatchMergeActions}
align={ALIGN_OPTIONS.LEFT}
label="Person 1"
disabled={!!initialLeftUuid}
/>
</Col>
<Col md={4} id="mid-merge-per-col">
Expand Down Expand Up @@ -450,7 +470,13 @@ const peopleFilters = {
}
}

const PersonColumn = ({ align, label, mergeState, dispatchMergeActions }) => {
const PersonColumn = ({
align,
label,
disabled,
mergeState,
dispatchMergeActions
}) => {
const person = mergeState[align]
const idForPerson = label.replace(/\s+/g, "")

Expand All @@ -469,23 +495,16 @@ const PersonColumn = ({ align, label, mergeState, dispatchMergeActions }) => {
overlayRenderRow={PersonSimpleOverlayRow}
filterDefs={peopleFilters}
onChange={value => {
const newValue = value
if (newValue?.customFields) {
newValue[DEFAULT_CUSTOM_FIELDS_PARENT] = utils.parseJsonSafe(
value.customFields
)
}
if (newValue?.customSensitiveInformation) {
newValue[SENSITIVE_CUSTOM_FIELDS_PARENT] =
utils.parseSensitiveFields(value.customSensitiveInformation)
}
value?.fixupFields()
dispatchMergeActions(setMergeable(value, align))
}}
objectType={Person}
valueKey="name"
fields={Person.allFieldsQuery}
addon={PEOPLE_ICON}
vertical
disabled={disabled}
showRemoveButton={!disabled}
/>
</ColTitle>
{areAllSet(person) && (
Expand Down Expand Up @@ -765,7 +784,7 @@ const PersonColumn = ({ align, label, mergeState, dispatchMergeActions }) => {
Object.entries(Settings.fields.person.customFields).map(
([fieldName, fieldConfig]) => {
const fieldValue =
person[DEFAULT_CUSTOM_FIELDS_PARENT][fieldName]
person?.[DEFAULT_CUSTOM_FIELDS_PARENT]?.[fieldName]
return (
<MergeField
key={fieldName}
Expand Down Expand Up @@ -794,7 +813,7 @@ const PersonColumn = ({ align, label, mergeState, dispatchMergeActions }) => {
Settings.fields.person.customSensitiveInformation
).map(([fieldName, fieldConfig]) => {
const fieldValue =
person[SENSITIVE_CUSTOM_FIELDS_PARENT][fieldName]
person?.[SENSITIVE_CUSTOM_FIELDS_PARENT]?.[fieldName]
return (
<MergeField
key={fieldName}
Expand Down Expand Up @@ -845,6 +864,7 @@ const PersonCol = styled.div`
PersonColumn.propTypes = {
align: PropTypes.oneOf(["left", "right"]).isRequired,
label: PropTypes.string.isRequired,
disabled: PropTypes.bool,
mergeState: PropTypes.object,
dispatchMergeActions: PropTypes.func
}
Expand Down
Loading
Loading