mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
8619b219e7
* wip * Use id instead of title Settings UI tweaks * test * Add toggle for all providers * Remove 'Abstract' embed, no longer available
158 lines
4.6 KiB
TypeScript
158 lines
4.6 KiB
TypeScript
import debounce from "lodash/debounce";
|
|
import { observer } from "mobx-react";
|
|
import { BrowserIcon } from "outline-icons";
|
|
import * as React from "react";
|
|
import { useTranslation, Trans } from "react-i18next";
|
|
import { toast } from "sonner";
|
|
import embeds from "@shared/editor/embeds";
|
|
import { TeamPreference } from "@shared/types";
|
|
import Heading from "~/components/Heading";
|
|
import Switch from "~/components/Switch";
|
|
import Text from "~/components/Text";
|
|
import useCurrentTeam from "~/hooks/useCurrentTeam";
|
|
import { IntegrationScene } from "./components/IntegrationScene";
|
|
import SettingRow from "./components/SettingRow";
|
|
import { HStack } from "~/components/primitives/HStack";
|
|
|
|
/** List of embed providers available for configuration. */
|
|
const providers = embeds.filter((e) => e.id !== "embed");
|
|
|
|
function Embeds() {
|
|
const team = useCurrentTeam();
|
|
const { t } = useTranslation();
|
|
|
|
const showSuccessMessage = React.useMemo(
|
|
() =>
|
|
debounce(() => {
|
|
toast.success(t("Settings saved"));
|
|
}, 250),
|
|
[t]
|
|
);
|
|
|
|
const saveData = React.useCallback(
|
|
async (newData: Record<string, unknown>) => {
|
|
try {
|
|
await team.save(newData);
|
|
showSuccessMessage();
|
|
} catch (err) {
|
|
toast.error((err as Error).message);
|
|
}
|
|
},
|
|
[team, showSuccessMessage]
|
|
);
|
|
|
|
const handleDocumentEmbedsChange = React.useCallback(
|
|
async (checked: boolean) => {
|
|
await saveData({ documentEmbeds: checked });
|
|
},
|
|
[saveData]
|
|
);
|
|
|
|
const handleToggleEmbed = React.useCallback(
|
|
async (id: string, enabled: boolean) => {
|
|
const disabledEmbeds =
|
|
(team.getPreference(TeamPreference.DisabledEmbeds) as string[]) || [];
|
|
|
|
const updated = enabled
|
|
? disabledEmbeds.filter((t) => t !== id)
|
|
: [...disabledEmbeds, id];
|
|
|
|
team.setPreference(TeamPreference.DisabledEmbeds, updated);
|
|
await saveData({
|
|
preferences: { ...team.preferences },
|
|
});
|
|
},
|
|
[team, saveData]
|
|
);
|
|
|
|
const handleToggleAllEmbeds = React.useCallback(
|
|
async (enabled: boolean) => {
|
|
const updated = enabled ? [] : providers.map((e) => e.id);
|
|
|
|
team.setPreference(TeamPreference.DisabledEmbeds, updated);
|
|
await saveData({
|
|
preferences: { ...team.preferences },
|
|
});
|
|
},
|
|
[team, saveData]
|
|
);
|
|
|
|
const disabledEmbeds =
|
|
(team.getPreference(TeamPreference.DisabledEmbeds) as string[]) || [];
|
|
|
|
return (
|
|
<IntegrationScene title={t("Embeds")} icon={<BrowserIcon />}>
|
|
<Heading>{t("Embeds")}</Heading>
|
|
|
|
<SettingRow
|
|
label={t("Enabled")}
|
|
name="documentEmbeds"
|
|
description={t(
|
|
"Allow supported providers to be inserted as interactive embeds in documents."
|
|
)}
|
|
>
|
|
<Switch
|
|
id="documentEmbeds"
|
|
checked={team.documentEmbeds}
|
|
onChange={handleDocumentEmbedsChange}
|
|
/>
|
|
</SettingRow>
|
|
|
|
{team.documentEmbeds && (
|
|
<>
|
|
<Heading as="h2">{t("Providers")}</Heading>
|
|
<Text as="p" type="secondary">
|
|
<Trans>
|
|
Enabled providers will appear in the editor slash menu and embed
|
|
automatically when a compatible link is pasted. Existing embeds in
|
|
documents will continue to display regardless of these settings.
|
|
</Trans>
|
|
</Text>
|
|
<SettingRow
|
|
name="allEmbeds"
|
|
label={t("All providers")}
|
|
compact
|
|
border={false}
|
|
>
|
|
<Switch
|
|
id="allEmbeds"
|
|
checked={disabledEmbeds.length === 0}
|
|
onChange={handleToggleAllEmbeds}
|
|
/>
|
|
</SettingRow>
|
|
{providers.map((embed) => {
|
|
const enabled = !disabledEmbeds.includes(embed.id);
|
|
return (
|
|
<SettingRow
|
|
key={embed.id}
|
|
name={embed.title}
|
|
label={
|
|
<HStack
|
|
style={{ filter: enabled ? "none" : "grayscale(100%)" }}
|
|
>
|
|
{embed.icon}
|
|
<Text type={enabled ? undefined : "tertiary"}>
|
|
{embed.title}
|
|
</Text>
|
|
</HStack>
|
|
}
|
|
compact
|
|
>
|
|
<Switch
|
|
id={embed.id}
|
|
checked={enabled}
|
|
onChange={(checked: boolean) =>
|
|
handleToggleEmbed(embed.id, checked)
|
|
}
|
|
/>
|
|
</SettingRow>
|
|
);
|
|
})}
|
|
</>
|
|
)}
|
|
</IntegrationScene>
|
|
);
|
|
}
|
|
|
|
export default observer(Embeds);
|