import { Component } from "react";
import { withTranslation, TFunction } from "react-i18next";
import DataUri from "../../Core/DataUri";
import filterOutUndefined from "../../Core/filterOutUndefined";
import JsonValue, { JsonObject } from "../../Core/Json";
import ViewState from "../../ReactViewModels/ViewState";
import Icon from "../../Styled/Icon";
import { withViewState } from "../Context";
import Styles from "./feature-info-download.scss";
import Dropdown from "../Generic/Dropdown";
class FeatureInfoDownload extends Component<{
data: JsonObject;
name: string;
viewState: ViewState;
t: TFunction;
}> {
getLinks() {
const csv = generateCsvData(this.props.data);
return filterOutUndefined([
csv
? {
href: DataUri.make("csv", csv),
download: `${this.props.name}.csv`,
label: "CSV"
}
: undefined,
{
href: DataUri.make("json", JSON.stringify(this.props.data)),
download: `${this.props.name}.json`,
label: "JSON"
}
]);
}
render() {
const { t } = this.props;
const links = this.getLinks();
const icon = (
);
return (
{t("featureInfo.download")}
);
}
}
/**
* Turns a 2-dimensional javascript object into a CSV string, with the first row being the property names and the second
* row being the data. If the object is too hierarchical to be made into a CSV, returns undefined.
*/
function generateCsvData(data: JsonObject) {
const row1 = [];
const row2 = [];
const keys = Object.keys(data);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const type = typeof data[key];
// If data is too hierarchical to fit in a table, just return undefined as we can't generate a CSV.
if (type === "object" && data[key] !== null) {
// covers both objects and arrays.
return;
}
if (type === "function") {
// Ignore template functions we may add.
continue;
}
row1.push(makeSafeForCsv(key));
row2.push(makeSafeForCsv(data[key]));
}
return row1.join(",") + "\n" + row2.join(",");
}
/**
* Makes a string safe for insertion into a CSV by wrapping it in inverted commas (") and changing inverted commas within
* it to double-inverted-commas ("") as per CSV convention.
*/
function makeSafeForCsv(value: JsonValue) {
value = value ? `${value}` : "";
return '"' + value.replace(/"/g, '""') + '"';
}
export default withTranslation()(withViewState(FeatureInfoDownload));