terriajs
Version:
Geospatial data visualization platform.
127 lines (113 loc) • 4 kB
JSX
import createReactClass from "create-react-class";
import naturalSort from "javascript-natural-sort";
import { runInAction } from "mobx";
import { observer } from "mobx-react";
import Mustache from "mustache";
import PropTypes from "prop-types";
import React from "react";
import { withTranslation } from "react-i18next";
import isDefined from "../../Core/isDefined";
import CommonStrata from "../../Models/Definition/CommonStrata";
import Box from "../../Styled/Box";
import { item } from "../Custom/Chart/tooltip.scss";
import Collapsible from "../Custom/Collapsible/Collapsible";
import parseCustomMarkdownToReact from "../Custom/parseCustomMarkdownToReact";
import MetadataTable from "./MetadataTable";
naturalSort.insensitive = true;
Mustache.escape = function (string) {
return string;
};
/**
* CatalogItem-defined sections that sit within the preview description. These are ordered according to the catalog item's
* order if available.
*/
const DataPreviewSections = observer(
createReactClass({
displayName: "DataPreviewSections",
propTypes: {
metadataItem: PropTypes.object.isRequired,
t: PropTypes.func.isRequired
},
sortInfoSections(items) {
const infoSectionOrder = this.props.metadataItem.infoSectionOrder;
items.sort(function (a, b) {
const aIndex = infoSectionOrder.indexOf(a.name);
const bIndex = infoSectionOrder.indexOf(b.name);
if (aIndex >= 0 && bIndex < 0) {
return -1;
} else if (aIndex < 0 && bIndex >= 0) {
return 1;
} else if (aIndex < 0 && bIndex < 0) {
return naturalSort(a.name, b.name);
}
return aIndex - bIndex;
});
return items.filter(
(item) =>
isDefined(item.content ?? item.contentAsObject) &&
(item.content ?? item.contentAsObject) !== null &&
item.content !== ""
);
},
clickInfoSection(reportName, isOpen) {
const info = this.props.metadataItem.info;
const clickedInfo = info.find((report) => report.name === reportName);
if (isDefined(clickedInfo)) {
runInAction(() => {
clickedInfo.setTrait(CommonStrata.user, "show", isOpen);
});
}
return false;
},
render() {
const metadataItem = this.props.metadataItem;
const items = metadataItem.hideSource
? metadataItem.infoWithoutSources
: metadataItem.info.slice();
const renderSection = (item) => {
let content = item.content;
try {
content = Mustache.render(content, metadataItem);
} catch (error) {
console.log(
`FAILED to parse info section ${item.name} for ${metadataItem.name}`
);
console.log(error);
}
return parseCustomMarkdownToReact(content, {
catalogItem: metadataItem
});
};
return (
<div>
<For each="item" index="i" of={this.sortInfoSections(items)}>
<Box paddedVertically displayInlineBlock fullWidth key={i}>
<Collapsible
key={i}
light={false}
title={item.name}
isOpen={item.show}
onToggle={(show) =>
this.clickInfoSection.bind(this, item.name, show)()
}
bodyTextProps={{ medium: true }}
>
<Choose>
<When condition={item.content?.length > 0}>
{renderSection(item)}
</When>
<When condition={item.contentAsObject !== undefined}>
<Box paddedVertically={3} fullWidth>
<MetadataTable metadataItem={item.contentAsObject} />
</Box>
</When>
</Choose>
</Collapsible>
</Box>
</For>
</div>
);
}
})
);
export default withTranslation()(DataPreviewSections);