-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: Split and simplify import/export pages in prep for more options * minor fixes * File operations for imports * test * icons
- Loading branch information
Showing
27 changed files
with
620 additions
and
453 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import * as React from "react"; | ||
import styled from "styled-components"; | ||
|
||
export default function Spinner(props: React.HTMLAttributes<HTMLOrSVGElement>) { | ||
return ( | ||
<SVG | ||
width="16px" | ||
height="16px" | ||
viewBox="0 0 16 16" | ||
xmlns="http://www.w3.org/2000/svg" | ||
{...props} | ||
> | ||
<Circle | ||
fill="none" | ||
strokeWidth="2" | ||
strokeLinecap="round" | ||
cx="8" | ||
cy="8" | ||
r="6" | ||
></Circle> | ||
</SVG> | ||
); | ||
} | ||
|
||
const SVG = styled.svg` | ||
@keyframes rotator { | ||
0% { | ||
transform: rotate(0deg); | ||
} | ||
100% { | ||
transform: rotate(270deg); | ||
} | ||
} | ||
animation: rotator 1.4s linear infinite; | ||
margin: 4px; | ||
`; | ||
|
||
const Circle = styled.circle` | ||
@keyframes dash { | ||
0% { | ||
stroke-dashoffset: 47; | ||
} | ||
50% { | ||
stroke-dashoffset: 11; | ||
transform: rotate(135deg); | ||
} | ||
100% { | ||
stroke-dashoffset: 47; | ||
transform: rotate(450deg); | ||
} | ||
} | ||
stroke: ${(props) => props.theme.textSecondary}; | ||
stroke-dasharray: 46; | ||
stroke-dashoffset: 0; | ||
transform-origin: center; | ||
animation: dash 1.4s ease-in-out infinite; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { observer } from "mobx-react"; | ||
import { DownloadIcon } from "outline-icons"; | ||
import * as React from "react"; | ||
import { useTranslation, Trans } from "react-i18next"; | ||
import FileOperation from "~/models/FileOperation"; | ||
import Button from "~/components/Button"; | ||
import Heading from "~/components/Heading"; | ||
import HelpText from "~/components/HelpText"; | ||
import PaginatedList from "~/components/PaginatedList"; | ||
import Scene from "~/components/Scene"; | ||
import Subheading from "~/components/Subheading"; | ||
import useCurrentUser from "~/hooks/useCurrentUser"; | ||
import useStores from "~/hooks/useStores"; | ||
import useToasts from "~/hooks/useToasts"; | ||
import FileOperationListItem from "./components/FileOperationListItem"; | ||
|
||
function Export() { | ||
const { t } = useTranslation(); | ||
const user = useCurrentUser(); | ||
const { fileOperations, collections } = useStores(); | ||
const { showToast } = useToasts(); | ||
const [isLoading, setLoading] = React.useState(false); | ||
const [isExporting, setExporting] = React.useState(false); | ||
|
||
const handleExport = React.useCallback( | ||
async (ev: React.SyntheticEvent) => { | ||
ev.preventDefault(); | ||
setLoading(true); | ||
|
||
try { | ||
await collections.export(); | ||
setExporting(true); | ||
showToast(t("Export in progress…")); | ||
} finally { | ||
setLoading(false); | ||
} | ||
}, | ||
[t, collections, showToast] | ||
); | ||
|
||
const handleDelete = React.useCallback( | ||
async (fileOperation: FileOperation) => { | ||
try { | ||
await fileOperations.delete(fileOperation); | ||
showToast(t("Export deleted")); | ||
} catch (err) { | ||
showToast(err.message, { | ||
type: "error", | ||
}); | ||
} | ||
}, | ||
[fileOperations, showToast, t] | ||
); | ||
|
||
return ( | ||
<Scene title={t("Export")} icon={<DownloadIcon color="currentColor" />}> | ||
<Heading>{t("Export")}</Heading> | ||
<HelpText> | ||
<Trans | ||
defaults="A full export might take some time, consider exporting a single document or collection. The exported data is a zip of your documents in Markdown format. You may leave this page once the export has started – we will email a link to <em>{{ userEmail }}</em> when it’s complete." | ||
values={{ | ||
userEmail: user.email, | ||
}} | ||
components={{ | ||
em: <strong />, | ||
}} | ||
/> | ||
</HelpText> | ||
<Button | ||
type="submit" | ||
onClick={handleExport} | ||
disabled={isLoading || isExporting} | ||
primary | ||
> | ||
{isExporting | ||
? t("Export Requested") | ||
: isLoading | ||
? `${t("Requesting Export")}…` | ||
: t("Export Data")} | ||
</Button> | ||
<br /> | ||
<PaginatedList | ||
items={fileOperations.exports} | ||
fetch={fileOperations.fetchPage} | ||
options={{ | ||
type: "export", | ||
}} | ||
heading={ | ||
<Subheading> | ||
<Trans>Recent exports</Trans> | ||
</Subheading> | ||
} | ||
renderItem={(item) => ( | ||
<FileOperationListItem | ||
key={item.id} | ||
fileOperation={item} | ||
handleDelete={handleDelete} | ||
/> | ||
)} | ||
/> | ||
</Scene> | ||
); | ||
} | ||
|
||
export default observer(Export); |
Oops, something went wrong.