Skip to content
This repository has been archived by the owner on Feb 1, 2024. It is now read-only.

Commit

Permalink
Add extended field handling to facility details
Browse files Browse the repository at this point in the history
Makes the facility details subsections expandable to show additional
content (details from other matches, claims, etc.) when not in embed
mode.

Adds extended field subsections (number of workers, native language
name, and so on) when values are present and the map is not in embed
mode.

Adds nonstandard/contributor field subsections when values are present
in embed mode.
  • Loading branch information
TaiWilkin committed Jan 18, 2022
1 parent 8301f13 commit 7169940
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 77 deletions.
55 changes: 39 additions & 16 deletions src/app/src/components/FacilityDetailSidebarContributors.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from 'react';
import { withStyles } from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';
import Divider from '@material-ui/core/Divider';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';

import FacilityDetailSidebarDetail from './FacilityDetailSidebarDetail';
import ShowOnly from './ShowOnly';
import BadgeVerified from './BadgeVerified';

import { makeProfileRouteLink } from '../util/util';

Expand All @@ -18,15 +20,24 @@ const detailsSidebarStyles = theme =>
textTransform: 'uppercase',
fontWeight: theme.typography.fontWeightMedium,
},
primaryText: {
wordWrap: 'break-word',
},
secondaryText: {
color: 'rgba(0, 0, 0, 0.54)',
display: 'flex',
alignItems: 'center',
fontSize: '12px',
justify: 'flex-end',
},
divider: {
backgroundColor: 'rgba(0, 0, 0, 0.06)',
icon: {
color: 'rgb(106, 106, 106)',
fontSize: '24px',
fontWeight: 300,
textAlign: 'center',
},
contributor: {
boxShadow: '0px -1px 0px 0px rgb(240, 240, 240)',
},
});

Expand All @@ -38,18 +49,30 @@ const FacilityDetailSidebarContributors = ({ classes, contributors, push }) => {
return (
<div className={classes.item}>
<Typography className={classes.label}>Contributors</Typography>
<Divider className={classes.divider} />
{contributors.map(contributor => (
<FacilityDetailSidebarDetail
primary={contributor.contributor_name}
secondary={contributor.list_name}
hasAdditionalContent={!!contributor.id}
hideTopDivider
additionalContentCount=""
onClick={() => push(makeProfileRouteLink(contributor.id))}
key={contributor.id}
verified={contributor.is_verified}
/>
{visibleContributors.map(contributor => (
<ListItem
button={!!contributor.id}
onClick={() => {
if (!contributor.id) return;
push(makeProfileRouteLink(contributor.id));
}}
key={`${contributor.id} ${contributor.list_name}`}
className={classes.contributor}
>
<ShowOnly when={contributor.is_verified}>
<BadgeVerified />
</ShowOnly>
<ListItemText
primary={contributor.contributor_name}
secondary={contributor.list_name}
classes={{ primary: classes.primaryText }}
/>
<ShowOnly when={!!contributor.id}>
<i
className={`${classes.icon} far fa-fw fa-angle-right`}
/>
</ShowOnly>
</ListItem>
))}
</div>
);
Expand Down
53 changes: 11 additions & 42 deletions src/app/src/components/FacilityDetailSidebarDetail.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import React from 'react';
import { withStyles } from '@material-ui/core/styles';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import Divider from '@material-ui/core/Divider';
import ArrowForwardIcon from '@material-ui/icons/ChevronRight';

import ShowOnly from './ShowOnly';
import BadgeVerified from './BadgeVerified';
Expand All @@ -13,56 +11,27 @@ const detailsSidebarStyles = () =>
primaryText: {
wordWrap: 'break-word',
},
secondaryText: {
color: 'rgba(0, 0, 0, 0.54)',
display: 'flex',
alignItems: 'center',
fontSize: '12px',
justify: 'flex-end',
},
divider: {
backgroundColor: 'rgba(0, 0, 0, 0.06)',
item: {
boxShadow: '0px -1px 0px 0px rgb(240, 240, 240)',
},
});

const FacilityDetailSidebarDetail = ({
hasAdditionalContent,
additionalContentCount,
primary,
secondary,
onClick,
hideTopDivider,
verified,
classes,
}) => (
<>
<ShowOnly when={!hideTopDivider}>
<Divider className={classes.divider} />
<ListItem className={classes.item}>
<ShowOnly when={verified}>
<BadgeVerified />
</ShowOnly>
<ListItem
button={hasAdditionalContent}
onClick={() => {
if (!hasAdditionalContent) return;
onClick();
}}
>
<ShowOnly when={verified}>
<BadgeVerified />
</ShowOnly>
<ListItemText
primary={primary}
secondary={secondary}
classes={{ primary: classes.primaryText }}
/>
<ShowOnly when={hasAdditionalContent}>
<div className={classes.secondaryText}>
<ListItemText secondary={additionalContentCount} />
<ArrowForwardIcon />
</div>
</ShowOnly>
</ListItem>
<Divider className={classes.divider} />
</>
<ListItemText
primary={primary}
secondary={secondary}
classes={{ primary: classes.primaryText }}
/>
</ListItem>
);

export default withStyles(detailsSidebarStyles)(FacilityDetailSidebarDetail);
90 changes: 85 additions & 5 deletions src/app/src/components/FacilityDetailSidebarExtended.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { useEffect } from 'react';
import React, { useEffect, useMemo } from 'react';
import { Redirect } from 'react-router';
import { connect } from 'react-redux';
import { withStyles } from '@material-ui/core/styles';
import get from 'lodash/get';
import includes from 'lodash/includes';
import filter from 'lodash/filter';
import moment from 'moment';
import CircularProgress from '@material-ui/core/CircularProgress';
import List from '@material-ui/core/List';
Expand All @@ -22,7 +23,10 @@ import {
resetSingleFacility,
} from '../actions/facilities';

import { facilitySidebarActions } from '../util/constants';
import {
facilitySidebarActions,
EXTENDED_FIELD_TYPES,
} from '../util/constants';

import {
makeReportADataIssueEmailLink,
Expand Down Expand Up @@ -80,6 +84,31 @@ const detailsSidebarStyles = theme =>
const formatAttribution = (createdAt, contributor) =>
`${moment(createdAt).format('LL')} by ${contributor}`;

/* eslint-disable camelcase */
const formatExtendedField = ({
value,
updated_at,
contributor_name,
verified,
id,
formatValue = v => v,
}) => ({
primary: formatValue(value),
secondary: formatAttribution(updated_at, contributor_name),
verified,
key: id,
});

const formatOtherValues = (data, fieldName, extendedFieldName) => [
...get(data, `properties.${fieldName}`, []).map(item => ({
primary: item,
key: item,
})),
...get(data, `properties.extended_fields.${extendedFieldName}`, []).map(
formatExtendedField,
),
];

const FacilityDetailSidebar = ({
classes,
data,
Expand All @@ -105,6 +134,16 @@ const FacilityDetailSidebar = ({
// Clears the selected facility when unmounted
useEffect(() => () => clearFacility(), []);

const otherNames = useMemo(
() => formatOtherValues(data, 'other_names', 'name'),
[data],
);

const otherAddresses = useMemo(
() => formatOtherValues(data, 'other_addresses', 'address'),
[data],
);

if (fetching) {
return (
<div className={classes.root}>
Expand Down Expand Up @@ -153,6 +192,30 @@ const FacilityDetailSidebar = ({
const isClaimed = !!data?.properties?.claim_info;
const claimFacility = () => push(makeClaimFacilityLink(oarId));

const renderExtendedField = ({ label, fieldName, formatValue }) => {
const values = get(data, `properties.extended_fields.${fieldName}`, []);
if (!values.length || !values[0]) return null;

const formatField = item =>
formatExtendedField({ ...item, formatValue });

const topValue = formatField(values[0]);

return (
<FacilityDetailSidebarItem
{...topValue}
label={label}
additionalContent={values.slice(1).map(formatField)}
embed={embed}
/>
);
};

const contributorFields = filter(
get(data, 'properties.contributor_fields', null),
field => field.value !== null,
);

return (
<div className={classes.root}>
<List className={classes.list}>
Expand All @@ -171,29 +234,46 @@ const FacilityDetailSidebar = ({
oarId={data.properties.oar_id}
onClaimFacility={claimFacility}
/>
<FacilityDetailSidebarItem label="OAR ID" primary={oarId} />
<FacilityDetailSidebarItem
label="OAR ID"
primary={oarId}
embed={embed}
/>
<FacilityDetailSidebarItem
label="Name"
primary={data.properties.name}
secondary={createdFrom}
additionalContent={data.properties.other_names}
additionalContent={otherNames}
embed={embed}
/>
<FacilityDetailSidebarItem
label="Address"
primary={`${data.properties.address} - ${data.properties.country_name}`}
secondary={createdFrom}
additionalContent={data.properties.other_addresses}
additionalContent={otherAddresses}
embed={embed}
/>
<div style={{ padding: '0 16px' }}>
<FacilityDetailsStaticMap data={data} />
</div>
<FacilityDetailSidebarLocation data={data} embed={embed} />
<ShowOnly when={!embed}>
{EXTENDED_FIELD_TYPES.map(renderExtendedField)}

<FacilityDetailSidebarContributors
contributors={data.properties.contributors}
push={push}
/>
</ShowOnly>
<ShowOnly when={embed}>
{contributorFields.map(field => (
<FacilityDetailSidebarItem
label={field.label}
primary={field.value}
key={field.label}
/>
))}
</ShowOnly>
<div className={classes.actions}>
<ShowOnly when={!embed}>
<FacilityDetailSidebarAction
Expand Down
2 changes: 1 addition & 1 deletion src/app/src/components/FacilityDetailSidebarHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const getContent = ({
secondary: 'Claim this facility',
icon: <BadgeUnclaimed />,
style: {
background: 'rgb(9, 18, 50)',
background: 'rgb(61, 50, 138)',
color: 'rgb(255, 255, 255)',
},
};
Expand Down

0 comments on commit 7169940

Please sign in to comment.