mirror of
https://github.com/outline/outline.git
synced 2026-08-03 13:27:25 +03:00
Add Security upsell rows and Collections upsell page
Surfaces more Enterprise-only features in the community edition: - Adds locked upsell rows to the Security settings page for two-factor authentication, automatic sign-out, and an IP allowlist. These only render on self-hosted instances, where the real settings are not available. - Adds a Collections placeholder page to the upsell plugin advertising workspace-wide collection administration. Relocates the shared EnterpriseBadge and UpsellSettingRow components from the plugin into app/scenes/Settings/components so core settings pages and the plugin can both consume them without inverting the app/plugin dependency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ca46gcmqU5HGgoK8SFHUx
This commit is contained in:
@@ -18,6 +18,7 @@ import useCurrentTeam from "~/hooks/useCurrentTeam";
|
||||
import useStores from "~/hooks/useStores";
|
||||
import isCloudHosted from "~/utils/isCloudHosted";
|
||||
import SettingRow from "./components/SettingRow";
|
||||
import { UpsellSettingRow } from "./components/UpsellSettingRow";
|
||||
|
||||
function Security() {
|
||||
const { dialogs } = useStores();
|
||||
@@ -312,6 +313,24 @@ function Security() {
|
||||
onChange={handlePasskeysEnabledChange}
|
||||
/>
|
||||
</SettingRow>
|
||||
{!isCloudHosted && (
|
||||
<>
|
||||
<UpsellSettingRow
|
||||
name="twoFactorRequired"
|
||||
label={t("Two-factor authentication")}
|
||||
description={t(
|
||||
"Require members to configure two-factor authentication to access the workspace."
|
||||
)}
|
||||
/>
|
||||
<UpsellSettingRow
|
||||
name="sessionTimeout"
|
||||
label={t("Automatic sign-out")}
|
||||
description={t(
|
||||
"Automatically sign out members after a configurable period of inactivity."
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Heading as="h2">{t("Behavior")}</Heading>
|
||||
<SettingRow
|
||||
@@ -412,6 +431,15 @@ function Security() {
|
||||
/>
|
||||
</SettingRow>
|
||||
)}
|
||||
{!isCloudHosted && (
|
||||
<UpsellSettingRow
|
||||
name="ipAllowlist"
|
||||
label={t("IP allowlist")}
|
||||
description={t(
|
||||
"Restrict workspace access to an approved list of IP addresses or ranges."
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</Scene>
|
||||
);
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,8 +2,8 @@ import * as React from "react";
|
||||
import styled from "styled-components";
|
||||
import Flex from "~/components/Flex";
|
||||
import Switch from "~/components/Switch";
|
||||
import SettingRow from "~/scenes/Settings/components/SettingRow";
|
||||
import { EnterpriseBadge } from "./EnterpriseBadge";
|
||||
import SettingRow from "./SettingRow";
|
||||
|
||||
type Props = {
|
||||
/** A unique name for the row, used to associate the label. */
|
||||
@@ -0,0 +1,42 @@
|
||||
import { CollectionIcon } from "outline-icons";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { UpsellScene } from "./components/UpsellScene";
|
||||
|
||||
/**
|
||||
* Upsell placeholder for the Enterprise-only collection management page, which
|
||||
* lets workspace admins administer the permissions and settings of every
|
||||
* collection, including private ones.
|
||||
*
|
||||
* @returns The rendered upsell scene.
|
||||
*/
|
||||
export default function Collections() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<UpsellScene
|
||||
title={t("Collections")}
|
||||
icon={<CollectionIcon />}
|
||||
description={t(
|
||||
"Manage the permissions and settings of all collections in the knowledge base. As a workspace admin you can also administer private collections."
|
||||
)}
|
||||
features={[
|
||||
{
|
||||
name: "collections-administer-private",
|
||||
label: t("Administer private collections"),
|
||||
description: t(
|
||||
"View and manage collections that have not been explicitly shared with you."
|
||||
),
|
||||
control: "none",
|
||||
},
|
||||
{
|
||||
name: "collections-bulk-permissions",
|
||||
label: t("Bulk permissions"),
|
||||
description: t(
|
||||
"Review and update sharing and access for every collection from one place."
|
||||
),
|
||||
control: "none",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -10,8 +10,8 @@ import Heading from "~/components/Heading";
|
||||
import Scene from "~/components/Scene";
|
||||
import Text from "~/components/Text";
|
||||
import env from "~/env";
|
||||
import { EnterpriseBadge } from "./EnterpriseBadge";
|
||||
import { UpsellSettingRow } from "./UpsellSettingRow";
|
||||
import { EnterpriseBadge } from "~/scenes/Settings/components/EnterpriseBadge";
|
||||
import { UpsellSettingRow } from "~/scenes/Settings/components/UpsellSettingRow";
|
||||
|
||||
/** A single Enterprise-only setting to preview within an upsell page. */
|
||||
export type UpsellFeature = {
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { BuildingBlocksIcon, HistoryIcon, SearchIcon } from "outline-icons";
|
||||
import {
|
||||
BuildingBlocksIcon,
|
||||
CollectionIcon,
|
||||
HistoryIcon,
|
||||
SearchIcon,
|
||||
} from "outline-icons";
|
||||
import { createLazyComponent } from "~/components/LazyLoad";
|
||||
import { Hook, PluginManager } from "~/utils/PluginManager";
|
||||
import config from "../plugin.json";
|
||||
@@ -18,6 +23,20 @@ PluginManager.add([
|
||||
component: createLazyComponent(() => import("./AuditLog")),
|
||||
},
|
||||
},
|
||||
{
|
||||
...config,
|
||||
id: "upsell-collections",
|
||||
name: "Collections",
|
||||
type: Hook.Settings,
|
||||
value: {
|
||||
group: "Workspace",
|
||||
after: "Groups",
|
||||
icon: CollectionIcon,
|
||||
description:
|
||||
"Manage permissions and settings for every collection, including private ones. Available in the Enterprise edition.",
|
||||
component: createLazyComponent(() => import("./Collections")),
|
||||
},
|
||||
},
|
||||
{
|
||||
...config,
|
||||
id: "upsell-data-attributes",
|
||||
|
||||
Reference in New Issue
Block a user