stash
This commit is contained in:
@ -121,9 +121,9 @@ class SettingsSidebar extends React.Component<Props> {
|
|||||||
/>
|
/>
|
||||||
{can.export && (
|
{can.export && (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to="/settings/export"
|
to="/settings/import-export"
|
||||||
icon={<DocumentIcon color="currentColor" />}
|
icon={<DocumentIcon color="currentColor" />}
|
||||||
label={t("Export Data")}
|
label={t("Import / Export")}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Section>
|
</Section>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { Switch, Route } from "react-router-dom";
|
import { Switch, Route } from "react-router-dom";
|
||||||
|
import ImportExport from "scenes/Settings/ImportExport";
|
||||||
import Settings from "scenes/Settings";
|
import Settings from "scenes/Settings";
|
||||||
import Details from "scenes/Settings/Details";
|
import Details from "scenes/Settings/Details";
|
||||||
import Export from "scenes/Settings/Export";
|
|
||||||
import Groups from "scenes/Settings/Groups";
|
import Groups from "scenes/Settings/Groups";
|
||||||
import Notifications from "scenes/Settings/Notifications";
|
import Notifications from "scenes/Settings/Notifications";
|
||||||
import People from "scenes/Settings/People";
|
import People from "scenes/Settings/People";
|
||||||
@ -27,7 +27,7 @@ export default function SettingsRoutes() {
|
|||||||
<Route exact path="/settings/notifications" component={Notifications} />
|
<Route exact path="/settings/notifications" component={Notifications} />
|
||||||
<Route exact path="/settings/integrations/slack" component={Slack} />
|
<Route exact path="/settings/integrations/slack" component={Slack} />
|
||||||
<Route exact path="/settings/integrations/zapier" component={Zapier} />
|
<Route exact path="/settings/integrations/zapier" component={Zapier} />
|
||||||
<Route exact path="/settings/export" component={Export} />
|
<Route exact path="/settings/import-export" component={ImportExport} />
|
||||||
</Switch>
|
</Switch>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
// @flow
|
|
||||||
import { observable } from "mobx";
|
|
||||||
import { observer, inject } from "mobx-react";
|
|
||||||
import * as React from "react";
|
|
||||||
import AuthStore from "stores/AuthStore";
|
|
||||||
import CollectionsStore from "stores/CollectionsStore";
|
|
||||||
import UiStore from "stores/UiStore";
|
|
||||||
|
|
||||||
import Button from "components/Button";
|
|
||||||
import CenteredContent from "components/CenteredContent";
|
|
||||||
import HelpText from "components/HelpText";
|
|
||||||
import PageTitle from "components/PageTitle";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
auth: AuthStore,
|
|
||||||
collections: CollectionsStore,
|
|
||||||
ui: UiStore,
|
|
||||||
};
|
|
||||||
|
|
||||||
@observer
|
|
||||||
class Export extends React.Component<Props> {
|
|
||||||
@observable isLoading: boolean = false;
|
|
||||||
@observable isExporting: boolean = false;
|
|
||||||
|
|
||||||
handleSubmit = async (ev: SyntheticEvent<>) => {
|
|
||||||
ev.preventDefault();
|
|
||||||
this.isLoading = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.props.collections.export();
|
|
||||||
this.isExporting = true;
|
|
||||||
this.props.ui.showToast("Export in progress…");
|
|
||||||
} finally {
|
|
||||||
this.isLoading = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { auth } = this.props;
|
|
||||||
if (!auth.user) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CenteredContent>
|
|
||||||
<PageTitle title="Export Data" />
|
|
||||||
<h1>Export Data</h1>
|
|
||||||
<HelpText>
|
|
||||||
Exporting your team’s documents may take a little time depending on
|
|
||||||
the size of your knowledge base. Consider exporting a single document
|
|
||||||
or collection instead.
|
|
||||||
</HelpText>
|
|
||||||
<HelpText>
|
|
||||||
Still want to export everything in your wiki? We’ll put together a zip
|
|
||||||
file of your collections and documents in Markdown format and email it
|
|
||||||
to <strong>{auth.user.email}</strong>.
|
|
||||||
</HelpText>
|
|
||||||
<Button
|
|
||||||
type="submit"
|
|
||||||
onClick={this.handleSubmit}
|
|
||||||
disabled={this.isLoading || this.isExporting}
|
|
||||||
primary
|
|
||||||
>
|
|
||||||
{this.isExporting
|
|
||||||
? "Export Requested"
|
|
||||||
: this.isLoading
|
|
||||||
? "Requesting Export…"
|
|
||||||
: "Export All Data"}
|
|
||||||
</Button>
|
|
||||||
</CenteredContent>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default inject("auth", "ui", "collections")(Export);
|
|
78
app/scenes/Settings/ImportExport.js
Normal file
78
app/scenes/Settings/ImportExport.js
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// @flow
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
import * as React from "react";
|
||||||
|
import { useTranslation, Trans } from "react-i18next";
|
||||||
|
import Button from "components/Button";
|
||||||
|
import CenteredContent from "components/CenteredContent";
|
||||||
|
import HelpText from "components/HelpText";
|
||||||
|
import PageTitle from "components/PageTitle";
|
||||||
|
import useCurrentUser from "hooks/useCurrentUser";
|
||||||
|
import useStores from "hooks/useStores";
|
||||||
|
|
||||||
|
function ImportExport() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const user = useCurrentUser();
|
||||||
|
const { ui, collections } = useStores();
|
||||||
|
const { showToast } = ui;
|
||||||
|
const [isLoading, setLoading] = React.useState(false);
|
||||||
|
const [isExporting, setExporting] = React.useState(false);
|
||||||
|
|
||||||
|
const handleImport = React.useCallback(async () => {
|
||||||
|
// TODO
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleExport = React.useCallback(
|
||||||
|
async (ev: SyntheticEvent<>) => {
|
||||||
|
ev.preventDefault();
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await collections.export();
|
||||||
|
setExporting(true);
|
||||||
|
showToast(t("Export in progress…"));
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[t, collections, showToast]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CenteredContent>
|
||||||
|
<PageTitle title={t("Import / Export")} />
|
||||||
|
<h1>{t("Import")}</h1>
|
||||||
|
<HelpText>
|
||||||
|
<Trans>
|
||||||
|
It is possible to import a zip file of folders and Markdown files.
|
||||||
|
</Trans>
|
||||||
|
</HelpText>
|
||||||
|
<Button type="submit" onClick={handleImport} primary>
|
||||||
|
{t("Import")}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<h1>{t("Export")}</h1>
|
||||||
|
<HelpText>
|
||||||
|
<Trans>
|
||||||
|
A full export might take some time, consider exporting a single
|
||||||
|
document or collection if possible. We’ll put together a zip of all
|
||||||
|
your documents in Markdown format and email it to{" "}
|
||||||
|
<strong>{{ userEmail: user.email }}</strong>.
|
||||||
|
</Trans>
|
||||||
|
</HelpText>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
onClick={handleExport}
|
||||||
|
disabled={isLoading || isExporting}
|
||||||
|
primary
|
||||||
|
>
|
||||||
|
{isExporting
|
||||||
|
? t("Export Requested")
|
||||||
|
: isLoading
|
||||||
|
? `${t("Requesting Export")}…`
|
||||||
|
: t("Export Data")}
|
||||||
|
</Button>
|
||||||
|
</CenteredContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default observer(ImportExport);
|
@ -101,7 +101,7 @@
|
|||||||
"People": "People",
|
"People": "People",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Share Links": "Share Links",
|
"Share Links": "Share Links",
|
||||||
"Export Data": "Export Data",
|
"Import / Export": "Import / Export",
|
||||||
"Integrations": "Integrations",
|
"Integrations": "Integrations",
|
||||||
"Installation": "Installation",
|
"Installation": "Installation",
|
||||||
"Settings": "Settings",
|
"Settings": "Settings",
|
||||||
|
Reference in New Issue
Block a user