Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

downloadable dataset context #795

Merged
merged 6 commits into from
Sep 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 36 additions & 24 deletions src/client/components/share-menu/share-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@
* limitations under the License.
*/

import { Dataset } from "plywood";
import * as React from "react";
import { ClientCustomization } from "../../../common/models/customization/customization";
import { Essence } from "../../../common/models/essence/essence";
import { ExternalView } from "../../../common/models/external-view/external-view";
import { Stage } from "../../../common/models/stage/stage";
import { Timekeeper } from "../../../common/models/timekeeper/timekeeper";
import { Binary } from "../../../common/utils/functional/functional";
import { Binary, Nullary } from "../../../common/utils/functional/functional";
import { Fn } from "../../../common/utils/general/general";
import { exportOptions, STRINGS } from "../../config/constants";
import { download, FileFormat, fileNameBase } from "../../utils/download/download";
import { DataSetWithTabOptions } from "../../views/cube-view/cube-view";
import { DownloadableDataset, DownloadableDatasetContext } from "../../views/cube-view/downloadable-dataset-context";
import { BubbleMenu } from "../bubble-menu/bubble-menu";
import { SafeCopyToClipboard } from "../safe-copy-to-clipboard/safe-copy-to-clipboard";

Expand All @@ -37,18 +38,23 @@ export interface ShareMenuProps {
openUrlShortenerModal: Binary<string, string, void>;
customization: ClientCustomization;
urlForEssence: (essence: Essence) => string;
getDownloadableDataset?: () => DataSetWithTabOptions;
}

type ExportProps = Pick<ShareMenuProps, "timekeeper" | "essence" | "onClose" | "getDownloadableDataset" | "customization">;
interface ExportProps {
getDataset: Nullary<Dataset | null>;
essence: Essence;
timekeeper: Timekeeper;
customization: ClientCustomization;
onClose: Fn;
}

function onExport(fileFormat: FileFormat, props: ExportProps) {
const { essence, timekeeper, onClose, getDownloadableDataset, customization: { locale: { exportEncoding } } } = props;
const dataSetWithTabOptions = getDownloadableDataset();
if (!dataSetWithTabOptions.dataset) return;
const { getDataset, essence, timekeeper, onClose, customization: { locale: { exportEncoding } } } = props;
const dataset = getDataset();
if (!dataset) return;
const fileName = fileNameBase(essence, timekeeper);

download(dataSetWithTabOptions, fileFormat, `${fileName}_export`, exportEncoding);
download(dataset, essence, fileFormat, `${fileName}_export`, exportEncoding);
onClose();
}

Expand Down Expand Up @@ -112,20 +118,26 @@ function externalViewItems({ customization: { externalViews = [] }, essence }: E
});
}

export function ShareMenu(props: ShareMenuProps) {
const { openOn, onClose } = props;

return <BubbleMenu
className="header-menu"
direction="down"
stage={Stage.fromSize(230, 200)}
openOn={openOn}
onClose={onClose}
>
<ul className="bubble-list">
{linkItems(props)}
{exportItems(props)}
{externalViewItems(props)}
</ul>
</BubbleMenu>;
export class ShareMenu extends React.Component<ShareMenuProps> {
static contextType = DownloadableDatasetContext;
context: DownloadableDataset;

render() {
const { getDataset } = this.context;
const { openOn, onClose } = this.props;

return <BubbleMenu
className="header-menu"
direction="down"
stage={Stage.fromSize(230, 200)}
openOn={openOn}
onClose={onClose}
>
<ul className="bubble-list">
{linkItems(this.props)}
{exportItems({ ...this.props, getDataset })}
{externalViewItems(this.props)}
</ul>
</BubbleMenu>;
}
}
4 changes: 1 addition & 3 deletions src/client/modals/raw-data-modal/raw-data-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import { exportOptions, STRINGS } from "../../config/constants";
import { classNames } from "../../utils/dom/dom";
import { download, FileFormat, fileNameBase } from "../../utils/download/download";
import { getVisibleSegments } from "../../utils/sizing/sizing";
import tabularOptions from "../../utils/tabular-options/tabular-options";
import "./raw-data-modal.scss";

const HEADER_HEIGHT = 30;
Expand Down Expand Up @@ -293,9 +292,8 @@ export class RawDataModal extends React.Component<RawDataModalProps, RawDataModa
const { dataset } = this.state;
const { essence, locale, timekeeper } = this.props;

const options = tabularOptions(essence);
const fileName = fileNameBase(essence, timekeeper);
download({ dataset, options }, fileFormat, `${fileName}_raw_data`, locale.exportEncoding);
download(dataset, essence, fileFormat, `${fileName}_raw_data`, locale.exportEncoding);
}

render() {
Expand Down
1 change: 0 additions & 1 deletion src/client/utils/dataset/sparse-dataset/test-fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*/

import { Dataset } from "plywood";
import { DataSetWithTabOptions } from "../../../views/cube-view/cube-view";

export const rawDataset = {
data: [
Expand Down
8 changes: 4 additions & 4 deletions src/client/utils/download/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Dataset, TabulatorOptions } from "plywood";
import { Essence } from "../../../common/models/essence/essence";
import { Timekeeper } from "../../../common/models/timekeeper/timekeeper";
import { formatUrlSafeDateTime } from "../../../common/utils/time/time";
import { DataSetWithTabOptions } from "../../views/cube-view/cube-view";
import tabularOptions from "../tabular-options/tabular-options";

export type FileFormat = "csv" | "tsv";

Expand All @@ -36,16 +36,16 @@ export function getMIMEType(fileType: FileFormat) {
function saveFile(part: string | Buffer, fileName: string, fileFormat: FileFormat, fileEncoding: string) {
const type = `${getMIMEType(fileFormat)};charset=${fileEncoding}`;
const blob = new Blob([part], { type });
fileSaver.saveAs(blob, `${fileName}.${fileFormat}`, true); // true == disable auto BOM
fileSaver.saveAs(blob, `${fileName}.${fileFormat}`, true);
mkuthan marked this conversation as resolved.
Show resolved Hide resolved
mkuthan marked this conversation as resolved.
Show resolved Hide resolved
}

function encodeContent(content: string, encoding: string): Promise<string | Buffer> {
if (encoding === "utf-8") return Promise.resolve(content);
return import("iconv-lite").then(iconv => iconv.encode(content, encoding));
}

export function download({ dataset, options }: DataSetWithTabOptions, fileFormat: FileFormat, fileName: string, fileEncoding: string) {
const result = datasetToFileString(dataset, fileFormat, options);
export function download(dataset: Dataset, essence: Essence, fileFormat: FileFormat, fileName: string, fileEncoding: string) {
const result = datasetToFileString(dataset, fileFormat, tabularOptions(essence));
encodeContent(result, fileEncoding).then(content => {
saveFile(content, fileName, fileFormat, fileEncoding);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import { ShareMenu } from "../../../components/share-menu/share-menu";
import { SvgIcon } from "../../../components/svg-icon/svg-icon";
import { TimezoneMenu } from "../../../components/timezone-menu/timezone-menu";
import { classNames } from "../../../utils/dom/dom";
import { DataSetWithTabOptions } from "../cube-view";
import "./cube-header-bar.scss";

export interface CubeHeaderBarProps {
Expand All @@ -47,7 +46,6 @@ export interface CubeHeaderBarProps {
openDruidQueryModal?: Fn;
openUrlShortenerModal?: Binary<string, string, void>;
customization?: ClientCustomization;
getDownloadableDataset?: () => DataSetWithTabOptions;
changeTimezone?: (timezone: Timezone) => void;
}

Expand Down Expand Up @@ -128,7 +126,7 @@ export class CubeHeaderBar extends React.Component<CubeHeaderBarProps, CubeHeade
closeShareMenu = () => this.setState({ shareMenuAnchor: null });

renderShareMenu() {
const { customization, essence, timekeeper, openUrlShortenerModal, urlForEssence, getDownloadableDataset } = this.props;
const { customization, essence, timekeeper, openUrlShortenerModal, urlForEssence } = this.props;
const { shareMenuAnchor } = this.state;
if (!shareMenuAnchor) return null;

Expand All @@ -140,7 +138,6 @@ export class CubeHeaderBar extends React.Component<CubeHeaderBarProps, CubeHeade
onClose={this.closeShareMenu}
customization={customization}
urlForEssence={urlForEssence}
getDownloadableDataset={getDownloadableDataset}
/>;
}

Expand Down
Loading