chore: Export improvements (#4617)

* wip

* i18n
This commit is contained in:
Tom Moor
2022-12-27 09:51:39 -08:00
committed by GitHub
parent ee37ba9355
commit 1b8dd9399c
17 changed files with 99 additions and 26 deletions

View File

@@ -29,6 +29,7 @@ import DocumentPermanentDelete from "~/scenes/DocumentPermanentDelete";
import DocumentTemplatizeDialog from "~/components/DocumentTemplatizeDialog";
import { createAction } from "~/actions";
import { DocumentSection } from "~/actions/sections";
import env from "~/env";
import history from "~/utils/history";
import {
documentInsightsUrl,
@@ -206,6 +207,33 @@ export const downloadDocumentAsHTML = createAction({
},
});
export const downloadDocumentAsPDF = createAction({
name: ({ t }) => t("PDF"),
section: DocumentSection,
keywords: "export",
icon: <DownloadIcon />,
iconInContextMenu: false,
visible: ({ activeDocumentId, stores }) =>
!!activeDocumentId &&
stores.policies.abilities(activeDocumentId).download &&
env.PDF_EXPORT_ENABLED,
perform: ({ activeDocumentId, t, stores }) => {
if (!activeDocumentId) {
return;
}
const id = stores.toasts.showToast(`${t("Exporting")}`, {
type: "loading",
timeout: 30 * 1000,
});
const document = stores.documents.get(activeDocumentId);
document
?.download("application/pdf")
.finally(() => id && stores.toasts.hideToast(id));
},
});
export const downloadDocumentAsMarkdown = createAction({
name: ({ t }) => t("Markdown"),
section: DocumentSection,
@@ -230,7 +258,11 @@ export const downloadDocument = createAction({
section: DocumentSection,
icon: <DownloadIcon />,
keywords: "export",
children: [downloadDocumentAsHTML, downloadDocumentAsMarkdown],
children: [
downloadDocumentAsHTML,
downloadDocumentAsPDF,
downloadDocumentAsMarkdown,
],
});
export const duplicateDocument = createAction({

View File

@@ -1,7 +1,11 @@
import * as React from "react";
import styled from "styled-components";
export default function Spinner(props: React.HTMLAttributes<HTMLOrSVGElement>) {
type Props = React.HTMLAttributes<HTMLOrSVGElement> & {
color?: string;
};
export default function Spinner({ color, ...props }: Props) {
return (
<SVG
width="16px"
@@ -11,6 +15,7 @@ export default function Spinner(props: React.HTMLAttributes<HTMLOrSVGElement>) {
{...props}
>
<Circle
$color={color}
fill="none"
strokeWidth="2"
strokeLinecap="round"
@@ -36,7 +41,7 @@ const SVG = styled.svg`
margin: 4px;
`;
const Circle = styled.circle`
const Circle = styled.circle<{ $color?: string }>`
@keyframes dash {
0% {
stroke-dashoffset: 47;
@@ -51,7 +56,7 @@ const Circle = styled.circle`
}
}
stroke: ${(props) => props.theme.textSecondary};
stroke: ${(props) => props.$color || props.theme.textSecondary};
stroke-dasharray: 46;
stroke-dashoffset: 0;
transform-origin: center;

View File

@@ -4,6 +4,7 @@ import * as React from "react";
import styled, { css } from "styled-components";
import { fadeAndScaleIn, pulse } from "~/styles/animations";
import { Toast as TToast } from "~/types";
import Spinner from "./Spinner";
type Props = {
onRequestClose: () => void;
@@ -56,6 +57,7 @@ function Toast({ closeAfterMs = 3000, onRequestClose, toast }: Props) {
onMouseLeave={handleResume}
>
<Container onClick={action ? undefined : onRequestClose}>
{type === "loading" && <Spinner color="currentColor" />}
{type === "info" && <InfoIcon color="currentColor" />}
{type === "success" && <CheckboxIcon checked color="currentColor" />}
{type === "warning" ||

View File

@@ -419,7 +419,9 @@ export default class Document extends ParanoidModel {
};
}
download = async (contentType: "text/html" | "text/markdown") => {
download = async (
contentType: "text/html" | "text/markdown" | "application/pdf"
) => {
await client.post(
`/documents.export`,
{

View File

@@ -124,7 +124,7 @@ export type Toast = {
id: string;
createdAt: string;
message: string;
type: "warning" | "error" | "info" | "success";
type: "warning" | "error" | "info" | "success" | "loading";
timeout?: number;
reoccurring?: number;
action?: {
@@ -176,7 +176,7 @@ export type SearchResult = {
};
export type ToastOptions = {
type: "warning" | "error" | "info" | "success";
type: "warning" | "error" | "info" | "success" | "loading";
timeout?: number;
action?: {
text: string;