Skip to content

Commit

Permalink
Merge pull request #4791 from wri/feat/new-metadata-endpoint-FLAG-879
Browse files Browse the repository at this point in the history
[FLAG-879] Implement new metadata endpoint
  • Loading branch information
willian-viana authored Mar 5, 2025
2 parents 0c2ad7a + 5f1c446 commit 49a74f8
Show file tree
Hide file tree
Showing 15 changed files with 1,143 additions and 142 deletions.
31 changes: 19 additions & 12 deletions components/modals/meta/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,26 @@ export const setModalMetaSettings = createThunkAction('setModalMetaSettings');

export const getModalMetaData = createThunkAction(
'getModalMetaData',
(metaKey) => (dispatch, getState) => {
const { modalMeta } = getState();
if (modalMeta && !modalMeta.loading) {
dispatch(setModalMetaLoading({ loading: true, error: false }));
getMetadata(metaKey)
.then((response) => {
dispatch(setModalMetaData(response.data));
})
.catch(() => {
dispatch(setModalMetaLoading({ loading: false, error: true }));
});
({ metakey, metaType }) =>
(dispatch, getState) => {
const { modalMeta } = getState();

if (modalMeta && !modalMeta.loading) {
dispatch(setModalMetaLoading({ loading: true, error: false }));

getMetadata(metakey, metaType)
.then((response) => {
if (metaType === 'widget') {
dispatch(setModalMetaData(response.data));
} else {
dispatch(setModalMetaData(response.data.metadata));
}
})
.catch(() => {
dispatch(setModalMetaLoading({ loading: false, error: true }));
});
}
}
}
);

export const setModalMetaClosed = createThunkAction(
Expand Down
125 changes: 64 additions & 61 deletions components/modals/meta/component.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React, { PureComponent } from 'react';
import ReactMarkdown from 'react-markdown';
import rehypeRaw from 'rehype-raw';

import PropTypes from 'prop-types';
import isEmpty from 'lodash/isEmpty';
import lowerCase from 'lodash/lowerCase';
import moment from 'moment';
import ReactHtmlParser from 'react-html-parser';
import { trackEvent } from 'utils/analytics';

import { Button, NoContent } from '@worldresources/gfw-components';
Expand All @@ -15,6 +17,7 @@ class ModalMeta extends PureComponent {
setModalMetaClosed: PropTypes.func,
metaData: PropTypes.object,
getModalMetaData: PropTypes.func,
metaType: PropTypes.string,
metakey: PropTypes.string,
tableData: PropTypes.object,
loading: PropTypes.bool,
Expand All @@ -23,16 +26,16 @@ class ModalMeta extends PureComponent {
};

componentDidMount() {
const { getModalMetaData, metakey } = this.props;
const { getModalMetaData, metakey, metaType } = this.props;
if (metakey) {
getModalMetaData(metakey);
getModalMetaData({ metakey, metaType });
}
}

componentDidUpdate(prevProps) {
const { getModalMetaData, metakey, metaData } = this.props;
const { getModalMetaData, metakey, metaData, metaType } = this.props;
if (metakey && metakey !== prevProps.metakey) {
getModalMetaData(metakey);
getModalMetaData({ metakey, metaType });
}

if (
Expand All @@ -48,24 +51,54 @@ class ModalMeta extends PureComponent {
}
}

/**
* We have 3 different properties to display the content date:
* content_date_description, content_date_range and content_date, in this order of priority
* @returns An object cointaing metadata rows with the correct content_date
*/
setContentDate() {
const {
tableData: {
resolution_description,
content_date_range = {},
content_date_description,
content_date,
...rest
},
} = this.props;

const entries = Object.entries(rest);
const { start_date = null, end_date = null } = content_date_range;

let contentDate = content_date;

if (start_date && end_date) {
contentDate = `${start_date.slice(0, 4)}-${end_date.slice(0, 4)}`;
}

if (content_date_description) {
contentDate = content_date_description;
}

entries.splice(1, 0, ['resolution', resolution_description]);
entries.splice(-2, 0, ['content_date', contentDate]);

return Object.fromEntries(entries);
}

getContent() {
const { metaData, tableData, loading, error, locationName } = this.props;
const {
subtitle,
overview,
citation,
map_service,
learn_more,
download_data,
amazon_link,
} = metaData || {};
const { subtitle, overview, citation, learn_more, download_data } =
metaData || {};

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

const tableDataWithContentDate = this.setContentDate(tableData);

return (
<div className="modal-meta-content">
{error && !loading && (
Expand All @@ -81,16 +114,18 @@ class ModalMeta extends PureComponent {
dangerouslySetInnerHTML={{ __html: subtitle }} // eslint-disable-line
/>
<div className="meta-table element-fullwidth">
{tableData &&
Object.keys(tableData).map((key) =>
tableData[key] ? (
{tableDataWithContentDate &&
Object.keys(tableDataWithContentDate).map((key) =>
tableDataWithContentDate[key] ? (
<div key={key} className="table-row">
<div
className="title-column"
dangerouslySetInnerHTML={{ __html: lowerCase(key) }} // eslint-disable-line
/>
<div className="description-column">
{this.parseContent(tableData[key])}
<ReactMarkdown rehypePlugins={[rehypeRaw]}>
{tableDataWithContentDate[key]}
</ReactMarkdown>
</div>
</div>
) : null
Expand All @@ -99,16 +134,24 @@ class ModalMeta extends PureComponent {
{overview && (
<div className="overview">
<h4>Overview</h4>
<div className="body">{this.parseContent(overview)}</div>
<div className="body">
<ReactMarkdown rehypePlugins={[rehypeRaw]}>
{overview}
</ReactMarkdown>
</div>
</div>
)}
{parsedCitation && (
<div className="citation">
<h5>Citation</h5>
<div className="body">{this.parseContent(parsedCitation)}</div>
<div className="body">
<ReactMarkdown rehypePlugins={[rehypeRaw]}>
{parsedCitation}
</ReactMarkdown>
</div>
</div>
)}
{(learn_more || download_data || map_service || amazon_link) && (
{(learn_more || download_data) && (
<div className="ext-actions">
{learn_more && (
<a
Expand All @@ -119,24 +162,6 @@ class ModalMeta extends PureComponent {
<Button size="medium">LEARN MORE</Button>
</a>
)}
{download_data && (
<a
href={download_data}
target="_blank"
rel="noopener noreferrer"
>
<Button size="medium">DOWNLOAD DATA</Button>
</a>
)}
{(map_service || amazon_link) && (
<a
href={map_service || amazon_link}
target="_blank"
rel="noopener noreferrer"
>
<Button size="medium">OPEN IN ARCGIS</Button>
</a>
)}
</div>
)}
</div>
Expand All @@ -145,28 +170,6 @@ class ModalMeta extends PureComponent {
);
}

parseContent = (html) => {
return (
<div>
{ReactHtmlParser(html, {
transform: (node) =>
node.name === 'a' ? (
<a
key={node.attribs.href}
href={node.attribs.href}
target="_blank"
rel="noopener noreferrer"
>
{node.children[0].data}
</a>
) : (
''
),
})}
</div>
);
};

render() {
const { metakey, setModalMetaClosed, metaData, loading } = this.props;
const { title } = metaData || {};
Expand Down
10 changes: 5 additions & 5 deletions components/modals/meta/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ const META_FIELDS = [
'overview',
'learn_more',
'download_data',
'map_service',
'amazon_link',
];
const TABLE_FIELDS = [
'function',
'resolution',
'resolution_description',
'geographic_coverage',
'source',
'frequency_of_updates',
'date_of_content',
'content_date',
'content_date_description',
'content_date_range',
'update_frequency',
'cautions',
'license',
];
Expand Down
6 changes: 6 additions & 0 deletions data/metadata-exception.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
"places_to_watch",
"nasa_fire_weather",
"waqi_air_quality",
"global_population_jrc"
]
61 changes: 61 additions & 0 deletions data/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
[
"umd_landsat_alerts",
"gfw_integrated_alerts",
"umd_glad_sentinel2_alerts",
"wur_radd_alerts",
"nasa_viirs_fire_alerts",
"umd_tree_cover_loss_from_fires",
"umd_tree_cover_gain_from_height",
"umd_tree_cover_loss",
"gfw_emerging_hot_spots",
"tsc_tree_cover_loss_drivers",
"umd_adm0_net_tree_cover_change_from_height",
"umd_tree_cover_density_2000",
"umd_tree_cover_density_2000",
"wri_tropical_tree_cover",
"wri_tropical_tree_cover",
"umd_regional_primary_forest_2001",
"umd_tree_cover_height_2020",
"wcs_forest_landscape_integrity_index",
"ifl_intact_forest_landscapes",
"esa_land_cover_2015",
"umd_soy_planted_area",
"gfw_planted_forests",
"gfw_peatlands",
"gmw_global_mangrove_extent",
"mapbiomas_bra_land_cover",
"ibge_bra_biomes",
"idn_land_cover_2017",
"gfw_managed_forests",
"gfw_mining_concessions",
"gfw_oil_palm",
"gfw_west_africa_cocoa_plot_density",
"gfw_universal_mill_list",
"rspo_oil_palm",
"gfw_oil_gas",
"gfw_wood_fiber",
"wdpa_protected_areas",
"intl_rivers_dam_hotspots",
"landmark_indigenous_and_community_lands",
"landmark_natural_resource_rights",
"licadho_khm_economic_land_concessions",
"khm_protected_areas",
"haka_idn_leuser",
"idn_forest_area",
"idn_forest_moratorium",
"osinfor_per_forest_concessions",
"osinfor_per_forest_concessions",
"osinfor_peru_permanent_production_forests",
"gfw_forest_carbon_gross_emissions",
"gfw_forest_carbon_net_flux",
"gfw_forest_carbon_gross_removals",
"whrc_aboveground_biomass_stock_2000",
"birdlife_biodiversity_intactness",
"birdlife_biodiversity_significance",
"birdlife_alliance_for_zero_extinction_sites",
"birdlife_key_biodiversity_areas",
"ci_biodiversity_hotspots",
"birdlife_endemic_bird_areas",
"osm_logging_roads",
"per_protected_areas"
]
2 changes: 1 addition & 1 deletion layouts/dashboards/component.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ class DashboardsPage extends PureComponent {
<MapControls className="map-controls" />
</Desktop>
<Share />
<ModalMeta />
<ModalMeta metaType="widget" />
{widgetAnchor && (
<ScrollTo target={widgetAnchor} afterScroll={clearScrollTo} />
)}
Expand Down
2 changes: 1 addition & 1 deletion layouts/embed/widget/component.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const WidgetEmbedPage = ({ widget, trase }) => (
<div className={cx('l-embed-widget-page', { '-trase': trase })}>
<Widgets className="embed-widget" embed widget={widget} />
<Share />
<ModalMeta />
<ModalMeta metaType="widget" />
<CountryDataProvider />
<WhitelistsProvider />
<GeodescriberProvider embed />
Expand Down
4 changes: 2 additions & 2 deletions layouts/map/component.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import MyGFWProvider from 'providers/mygfw-provider';
import MetaProvider from 'providers/meta-provider';

import ModalWelcome from 'components/modals/welcome';
import MetaModal from 'components/modals/meta';
import ModalMeta from 'components/modals/meta';
import ShareModal from 'components/modals/share';
import AreaOfInterestModal from 'components/modals/area-of-interest';
import ClimateModal from 'components/modals/climate';
Expand Down Expand Up @@ -96,7 +96,7 @@ class MainMapComponent extends PureComponent {
)}
<RecentImagery active={recentActive} />
<ShareModal />
<MetaModal />
<ModalMeta metaType="layer" />
<AreaOfInterestModal viewAfterSave clearAfterDelete canDelete />
<ClimateModal />
<FiresModal />
Expand Down
Loading

0 comments on commit 49a74f8

Please sign in to comment.