Skip to content

Commit 49a74f8

Browse files
Merge pull request #4791 from wri/feat/new-metadata-endpoint-FLAG-879
[FLAG-879] Implement new metadata endpoint
2 parents 0c2ad7a + 5f1c446 commit 49a74f8

File tree

15 files changed

+1143
-142
lines changed

15 files changed

+1143
-142
lines changed

components/modals/meta/actions.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,26 @@ export const setModalMetaSettings = createThunkAction('setModalMetaSettings');
88

99
export const getModalMetaData = createThunkAction(
1010
'getModalMetaData',
11-
(metaKey) => (dispatch, getState) => {
12-
const { modalMeta } = getState();
13-
if (modalMeta && !modalMeta.loading) {
14-
dispatch(setModalMetaLoading({ loading: true, error: false }));
15-
getMetadata(metaKey)
16-
.then((response) => {
17-
dispatch(setModalMetaData(response.data));
18-
})
19-
.catch(() => {
20-
dispatch(setModalMetaLoading({ loading: false, error: true }));
21-
});
11+
({ metakey, metaType }) =>
12+
(dispatch, getState) => {
13+
const { modalMeta } = getState();
14+
15+
if (modalMeta && !modalMeta.loading) {
16+
dispatch(setModalMetaLoading({ loading: true, error: false }));
17+
18+
getMetadata(metakey, metaType)
19+
.then((response) => {
20+
if (metaType === 'widget') {
21+
dispatch(setModalMetaData(response.data));
22+
} else {
23+
dispatch(setModalMetaData(response.data.metadata));
24+
}
25+
})
26+
.catch(() => {
27+
dispatch(setModalMetaLoading({ loading: false, error: true }));
28+
});
29+
}
2230
}
23-
}
2431
);
2532

2633
export const setModalMetaClosed = createThunkAction(

components/modals/meta/component.jsx

Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import React, { PureComponent } from 'react';
2+
import ReactMarkdown from 'react-markdown';
3+
import rehypeRaw from 'rehype-raw';
4+
25
import PropTypes from 'prop-types';
36
import isEmpty from 'lodash/isEmpty';
47
import lowerCase from 'lodash/lowerCase';
58
import moment from 'moment';
6-
import ReactHtmlParser from 'react-html-parser';
79
import { trackEvent } from 'utils/analytics';
810

911
import { Button, NoContent } from '@worldresources/gfw-components';
@@ -15,6 +17,7 @@ class ModalMeta extends PureComponent {
1517
setModalMetaClosed: PropTypes.func,
1618
metaData: PropTypes.object,
1719
getModalMetaData: PropTypes.func,
20+
metaType: PropTypes.string,
1821
metakey: PropTypes.string,
1922
tableData: PropTypes.object,
2023
loading: PropTypes.bool,
@@ -23,16 +26,16 @@ class ModalMeta extends PureComponent {
2326
};
2427

2528
componentDidMount() {
26-
const { getModalMetaData, metakey } = this.props;
29+
const { getModalMetaData, metakey, metaType } = this.props;
2730
if (metakey) {
28-
getModalMetaData(metakey);
31+
getModalMetaData({ metakey, metaType });
2932
}
3033
}
3134

3235
componentDidUpdate(prevProps) {
33-
const { getModalMetaData, metakey, metaData } = this.props;
36+
const { getModalMetaData, metakey, metaData, metaType } = this.props;
3437
if (metakey && metakey !== prevProps.metakey) {
35-
getModalMetaData(metakey);
38+
getModalMetaData({ metakey, metaType });
3639
}
3740

3841
if (
@@ -48,24 +51,54 @@ class ModalMeta extends PureComponent {
4851
}
4952
}
5053

54+
/**
55+
* We have 3 different properties to display the content date:
56+
* content_date_description, content_date_range and content_date, in this order of priority
57+
* @returns An object cointaing metadata rows with the correct content_date
58+
*/
59+
setContentDate() {
60+
const {
61+
tableData: {
62+
resolution_description,
63+
content_date_range = {},
64+
content_date_description,
65+
content_date,
66+
...rest
67+
},
68+
} = this.props;
69+
70+
const entries = Object.entries(rest);
71+
const { start_date = null, end_date = null } = content_date_range;
72+
73+
let contentDate = content_date;
74+
75+
if (start_date && end_date) {
76+
contentDate = `${start_date.slice(0, 4)}-${end_date.slice(0, 4)}`;
77+
}
78+
79+
if (content_date_description) {
80+
contentDate = content_date_description;
81+
}
82+
83+
entries.splice(1, 0, ['resolution', resolution_description]);
84+
entries.splice(-2, 0, ['content_date', contentDate]);
85+
86+
return Object.fromEntries(entries);
87+
}
88+
5189
getContent() {
5290
const { metaData, tableData, loading, error, locationName } = this.props;
53-
const {
54-
subtitle,
55-
overview,
56-
citation,
57-
map_service,
58-
learn_more,
59-
download_data,
60-
amazon_link,
61-
} = metaData || {};
91+
const { subtitle, overview, citation, learn_more, download_data } =
92+
metaData || {};
6293

6394
const parsedCitation =
6495
citation &&
6596
citation
6697
.replaceAll('[selected area name]', locationName)
6798
.replaceAll('[date]', moment().format('DD/MM/YYYY'));
6899

100+
const tableDataWithContentDate = this.setContentDate(tableData);
101+
69102
return (
70103
<div className="modal-meta-content">
71104
{error && !loading && (
@@ -81,16 +114,18 @@ class ModalMeta extends PureComponent {
81114
dangerouslySetInnerHTML={{ __html: subtitle }} // eslint-disable-line
82115
/>
83116
<div className="meta-table element-fullwidth">
84-
{tableData &&
85-
Object.keys(tableData).map((key) =>
86-
tableData[key] ? (
117+
{tableDataWithContentDate &&
118+
Object.keys(tableDataWithContentDate).map((key) =>
119+
tableDataWithContentDate[key] ? (
87120
<div key={key} className="table-row">
88121
<div
89122
className="title-column"
90123
dangerouslySetInnerHTML={{ __html: lowerCase(key) }} // eslint-disable-line
91124
/>
92125
<div className="description-column">
93-
{this.parseContent(tableData[key])}
126+
<ReactMarkdown rehypePlugins={[rehypeRaw]}>
127+
{tableDataWithContentDate[key]}
128+
</ReactMarkdown>
94129
</div>
95130
</div>
96131
) : null
@@ -99,16 +134,24 @@ class ModalMeta extends PureComponent {
99134
{overview && (
100135
<div className="overview">
101136
<h4>Overview</h4>
102-
<div className="body">{this.parseContent(overview)}</div>
137+
<div className="body">
138+
<ReactMarkdown rehypePlugins={[rehypeRaw]}>
139+
{overview}
140+
</ReactMarkdown>
141+
</div>
103142
</div>
104143
)}
105144
{parsedCitation && (
106145
<div className="citation">
107146
<h5>Citation</h5>
108-
<div className="body">{this.parseContent(parsedCitation)}</div>
147+
<div className="body">
148+
<ReactMarkdown rehypePlugins={[rehypeRaw]}>
149+
{parsedCitation}
150+
</ReactMarkdown>
151+
</div>
109152
</div>
110153
)}
111-
{(learn_more || download_data || map_service || amazon_link) && (
154+
{(learn_more || download_data) && (
112155
<div className="ext-actions">
113156
{learn_more && (
114157
<a
@@ -119,24 +162,6 @@ class ModalMeta extends PureComponent {
119162
<Button size="medium">LEARN MORE</Button>
120163
</a>
121164
)}
122-
{download_data && (
123-
<a
124-
href={download_data}
125-
target="_blank"
126-
rel="noopener noreferrer"
127-
>
128-
<Button size="medium">DOWNLOAD DATA</Button>
129-
</a>
130-
)}
131-
{(map_service || amazon_link) && (
132-
<a
133-
href={map_service || amazon_link}
134-
target="_blank"
135-
rel="noopener noreferrer"
136-
>
137-
<Button size="medium">OPEN IN ARCGIS</Button>
138-
</a>
139-
)}
140165
</div>
141166
)}
142167
</div>
@@ -145,28 +170,6 @@ class ModalMeta extends PureComponent {
145170
);
146171
}
147172

148-
parseContent = (html) => {
149-
return (
150-
<div>
151-
{ReactHtmlParser(html, {
152-
transform: (node) =>
153-
node.name === 'a' ? (
154-
<a
155-
key={node.attribs.href}
156-
href={node.attribs.href}
157-
target="_blank"
158-
rel="noopener noreferrer"
159-
>
160-
{node.children[0].data}
161-
</a>
162-
) : (
163-
''
164-
),
165-
})}
166-
</div>
167-
);
168-
};
169-
170173
render() {
171174
const { metakey, setModalMetaClosed, metaData, loading } = this.props;
172175
const { title } = metaData || {};

components/modals/meta/selectors.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ const META_FIELDS = [
1010
'overview',
1111
'learn_more',
1212
'download_data',
13-
'map_service',
14-
'amazon_link',
1513
];
1614
const TABLE_FIELDS = [
1715
'function',
18-
'resolution',
16+
'resolution_description',
1917
'geographic_coverage',
2018
'source',
21-
'frequency_of_updates',
22-
'date_of_content',
19+
'content_date',
20+
'content_date_description',
21+
'content_date_range',
22+
'update_frequency',
2323
'cautions',
2424
'license',
2525
];

data/metadata-exception.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
"places_to_watch",
3+
"nasa_fire_weather",
4+
"waqi_air_quality",
5+
"global_population_jrc"
6+
]

data/metadata.json

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
[
2+
"umd_landsat_alerts",
3+
"gfw_integrated_alerts",
4+
"umd_glad_sentinel2_alerts",
5+
"wur_radd_alerts",
6+
"nasa_viirs_fire_alerts",
7+
"umd_tree_cover_loss_from_fires",
8+
"umd_tree_cover_gain_from_height",
9+
"umd_tree_cover_loss",
10+
"gfw_emerging_hot_spots",
11+
"tsc_tree_cover_loss_drivers",
12+
"umd_adm0_net_tree_cover_change_from_height",
13+
"umd_tree_cover_density_2000",
14+
"umd_tree_cover_density_2000",
15+
"wri_tropical_tree_cover",
16+
"wri_tropical_tree_cover",
17+
"umd_regional_primary_forest_2001",
18+
"umd_tree_cover_height_2020",
19+
"wcs_forest_landscape_integrity_index",
20+
"ifl_intact_forest_landscapes",
21+
"esa_land_cover_2015",
22+
"umd_soy_planted_area",
23+
"gfw_planted_forests",
24+
"gfw_peatlands",
25+
"gmw_global_mangrove_extent",
26+
"mapbiomas_bra_land_cover",
27+
"ibge_bra_biomes",
28+
"idn_land_cover_2017",
29+
"gfw_managed_forests",
30+
"gfw_mining_concessions",
31+
"gfw_oil_palm",
32+
"gfw_west_africa_cocoa_plot_density",
33+
"gfw_universal_mill_list",
34+
"rspo_oil_palm",
35+
"gfw_oil_gas",
36+
"gfw_wood_fiber",
37+
"wdpa_protected_areas",
38+
"intl_rivers_dam_hotspots",
39+
"landmark_indigenous_and_community_lands",
40+
"landmark_natural_resource_rights",
41+
"licadho_khm_economic_land_concessions",
42+
"khm_protected_areas",
43+
"haka_idn_leuser",
44+
"idn_forest_area",
45+
"idn_forest_moratorium",
46+
"osinfor_per_forest_concessions",
47+
"osinfor_per_forest_concessions",
48+
"osinfor_peru_permanent_production_forests",
49+
"gfw_forest_carbon_gross_emissions",
50+
"gfw_forest_carbon_net_flux",
51+
"gfw_forest_carbon_gross_removals",
52+
"whrc_aboveground_biomass_stock_2000",
53+
"birdlife_biodiversity_intactness",
54+
"birdlife_biodiversity_significance",
55+
"birdlife_alliance_for_zero_extinction_sites",
56+
"birdlife_key_biodiversity_areas",
57+
"ci_biodiversity_hotspots",
58+
"birdlife_endemic_bird_areas",
59+
"osm_logging_roads",
60+
"per_protected_areas"
61+
]

layouts/dashboards/component.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ class DashboardsPage extends PureComponent {
216216
<MapControls className="map-controls" />
217217
</Desktop>
218218
<Share />
219-
<ModalMeta />
219+
<ModalMeta metaType="widget" />
220220
{widgetAnchor && (
221221
<ScrollTo target={widgetAnchor} afterScroll={clearScrollTo} />
222222
)}

layouts/embed/widget/component.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const WidgetEmbedPage = ({ widget, trase }) => (
1616
<div className={cx('l-embed-widget-page', { '-trase': trase })}>
1717
<Widgets className="embed-widget" embed widget={widget} />
1818
<Share />
19-
<ModalMeta />
19+
<ModalMeta metaType="widget" />
2020
<CountryDataProvider />
2121
<WhitelistsProvider />
2222
<GeodescriberProvider embed />

layouts/map/component.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import MyGFWProvider from 'providers/mygfw-provider';
1616
import MetaProvider from 'providers/meta-provider';
1717

1818
import ModalWelcome from 'components/modals/welcome';
19-
import MetaModal from 'components/modals/meta';
19+
import ModalMeta from 'components/modals/meta';
2020
import ShareModal from 'components/modals/share';
2121
import AreaOfInterestModal from 'components/modals/area-of-interest';
2222
import ClimateModal from 'components/modals/climate';
@@ -96,7 +96,7 @@ class MainMapComponent extends PureComponent {
9696
)}
9797
<RecentImagery active={recentActive} />
9898
<ShareModal />
99-
<MetaModal />
99+
<ModalMeta metaType="layer" />
100100
<AreaOfInterestModal viewAfterSave clearAfterDelete canDelete />
101101
<ClimateModal />
102102
<FiresModal />

0 commit comments

Comments
 (0)