mirror of
https://github.com/docmost/docmost.git
synced 2026-09-11 07:56:54 +08:00
feat(beta): public spaces (#2473)
This commit is contained in:
@@ -4,6 +4,8 @@ import AddSpaceMembersModal from "@/features/space/components/add-space-members-
|
||||
import React from "react";
|
||||
import SpaceDetails from "@/features/space/components/space-details.tsx";
|
||||
import SpaceSecuritySettings from "@/features/space/components/space-security-settings.tsx";
|
||||
import PublishSpaceSettings from "@/features/public-space/components/publish-space-settings.tsx";
|
||||
import { isPublicSpacesAllowed } from "@/features/public-space/utils/public-space-access.ts";
|
||||
import { useSpaceQuery } from "@/features/space/queries/space-query.ts";
|
||||
import { useSpaceAbility } from "@/features/space/permissions/use-space-ability.ts";
|
||||
import {
|
||||
@@ -11,6 +13,8 @@ import {
|
||||
SpaceCaslSubject,
|
||||
} from "@/features/space/permissions/permissions.type.ts";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAtom } from "jotai";
|
||||
import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts";
|
||||
|
||||
interface SpaceSettingsModalProps {
|
||||
spaceId: string;
|
||||
@@ -29,6 +33,13 @@ export default function SpaceSettingsModal({
|
||||
const spaceRules = space?.membership?.permissions;
|
||||
const spaceAbility = useSpaceAbility(spaceRules);
|
||||
|
||||
const [workspace] = useAtom(workspaceAtom);
|
||||
const allowPublicSpaces = isPublicSpacesAllowed(workspace);
|
||||
const canManageSettings = spaceAbility.can(
|
||||
SpaceCaslAction.Manage,
|
||||
SpaceCaslSubject.Settings,
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal.Root
|
||||
@@ -60,10 +71,12 @@ export default function SpaceSettingsModal({
|
||||
<Tabs.Tab fw={500} value="members">
|
||||
{t("Members")}
|
||||
</Tabs.Tab>
|
||||
{spaceAbility.can(
|
||||
SpaceCaslAction.Manage,
|
||||
SpaceCaslSubject.Settings,
|
||||
) && (
|
||||
{canManageSettings && allowPublicSpaces && (
|
||||
<Tabs.Tab fw={500} value="publish">
|
||||
{t("Publish")}
|
||||
</Tabs.Tab>
|
||||
)}
|
||||
{canManageSettings && (
|
||||
<Tabs.Tab fw={500} value="security">
|
||||
{t("Security")}
|
||||
</Tabs.Tab>
|
||||
@@ -114,6 +127,16 @@ export default function SpaceSettingsModal({
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</Tabs.Panel>
|
||||
|
||||
<Tabs.Panel value="publish">
|
||||
<ScrollArea h={580} scrollbarSize={5} pr={8}>
|
||||
<div style={{ paddingBottom: "100px" }}>
|
||||
{canManageSettings && allowPublicSpaces && (
|
||||
<PublishSpaceSettings space={space} />
|
||||
)}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</Tabs.Panel>
|
||||
</Tabs>
|
||||
</div>
|
||||
</Modal.Body>
|
||||
|
||||
@@ -35,7 +35,7 @@ import clsx from "clsx";
|
||||
import { useDisclosure } from "@mantine/hooks";
|
||||
import SpaceSettingsModal from "@/features/space/components/settings-modal.tsx";
|
||||
import { useGetSpaceBySlugQuery } from "@/features/space/queries/space-query.ts";
|
||||
import { getSpaceUrl } from "@/lib/config.ts";
|
||||
import { getSpaceUrl, isBetaPublicSpaces } from "@/lib/config.ts";
|
||||
import SpaceTree from "@/features/page/tree/components/space-tree.tsx";
|
||||
import { useSpaceAbility } from "@/features/space/permissions/use-space-ability.ts";
|
||||
import {
|
||||
@@ -106,6 +106,7 @@ export function SpaceSidebar() {
|
||||
spaceName={space?.name}
|
||||
spaceSlug={space?.slug}
|
||||
spaceIcon={space?.logo}
|
||||
isPublished={isBetaPublicSpaces() && space?.isPublished}
|
||||
/>
|
||||
</Group>
|
||||
</div>
|
||||
|
||||
@@ -2,24 +2,32 @@ import classes from "./switch-space.module.css";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { SpaceSelect } from "./space-select";
|
||||
import { getSpaceUrl } from "@/lib/config";
|
||||
import { Button, Popover, Text } from "@mantine/core";
|
||||
import { IconChevronDown, IconChevronUp } from "@tabler/icons-react";
|
||||
import { Button, Popover, Text, Tooltip } from "@mantine/core";
|
||||
import {
|
||||
IconChevronDown,
|
||||
IconChevronUp,
|
||||
IconWorld,
|
||||
} from "@tabler/icons-react";
|
||||
import { useDisclosure } from "@mantine/hooks";
|
||||
import { CustomAvatar } from "@/components/ui/custom-avatar.tsx";
|
||||
import { AvatarIconType } from "@/features/attachments/types/attachment.types.ts";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
interface SwitchSpaceProps {
|
||||
spaceName: string;
|
||||
spaceSlug: string;
|
||||
spaceIcon?: string;
|
||||
isPublished?: boolean;
|
||||
}
|
||||
|
||||
export function SwitchSpace({
|
||||
spaceName,
|
||||
spaceSlug,
|
||||
spaceIcon,
|
||||
isPublished,
|
||||
}: SwitchSpaceProps) {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const [opened, { close, toggle }] = useDisclosure(false);
|
||||
|
||||
@@ -61,6 +69,16 @@ export function SwitchSpace({
|
||||
<Text className={classes.spaceName} size="md" fw={500} lineClamp={1}>
|
||||
{spaceName}
|
||||
</Text>
|
||||
|
||||
{isPublished && (
|
||||
<Tooltip label={t("This space is public")}>
|
||||
<IconWorld
|
||||
size={14}
|
||||
aria-label={t("This space is public")}
|
||||
style={{ flexShrink: 0 }}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Button>
|
||||
</Popover.Target>
|
||||
<Popover.Dropdown>
|
||||
|
||||
@@ -30,6 +30,7 @@ export interface ISpace {
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
memberCount?: number;
|
||||
isPublished?: boolean;
|
||||
spaceId?: string;
|
||||
membership?: IMembership;
|
||||
settings?: ISpaceSettings;
|
||||
|
||||
Reference in New Issue
Block a user