feat: watch space (#2096)

This commit is contained in:
Philip Okugbe
2026-04-09 00:37:51 +01:00
committed by GitHub
parent 4966f9b152
commit da9b43681e
12 changed files with 449 additions and 75 deletions
@@ -9,6 +9,8 @@ import {
import {
IconArrowDown,
IconDots,
IconEye,
IconEyeOff,
IconFileExport,
IconHome,
IconPlus,
@@ -16,6 +18,11 @@ import {
IconSettings,
IconTrash,
} from "@tabler/icons-react";
import {
useSpaceWatchStatusQuery,
useWatchSpaceMutation,
useUnwatchSpaceMutation,
} from "@/features/space/queries/space-watcher-query.ts";
import classes from "./space-sidebar.module.css";
import React from "react";
import { useAtom } from "jotai";
@@ -160,13 +167,20 @@ export function SpaceSidebar() {
{t("Pages")}
</Text>
{spaceAbility.can(
SpaceCaslAction.Manage,
SpaceCaslSubject.Page,
) && (
<Group gap="xs">
<SpaceMenu spaceId={space.id} onSpaceSettings={openSettings} />
<Group gap="xs">
<SpaceMenu
spaceId={space.id}
canManagePages={spaceAbility.can(
SpaceCaslAction.Manage,
SpaceCaslSubject.Page,
)}
onSpaceSettings={openSettings}
/>
{spaceAbility.can(
SpaceCaslAction.Manage,
SpaceCaslSubject.Page,
) && (
<Tooltip label={t("Create page")} withArrow position="right">
<ActionIcon
variant="default"
@@ -177,8 +191,8 @@ export function SpaceSidebar() {
<IconPlus />
</ActionIcon>
</Tooltip>
</Group>
)}
)}
</Group>
</Group>
<div className={classes.pages}>
@@ -204,9 +218,14 @@ export function SpaceSidebar() {
interface SpaceMenuProps {
spaceId: string;
canManagePages: boolean;
onSpaceSettings: () => void;
}
function SpaceMenu({ spaceId, onSpaceSettings }: SpaceMenuProps) {
function SpaceMenu({
spaceId,
canManagePages,
onSpaceSettings,
}: SpaceMenuProps) {
const { t } = useTranslation();
const { spaceSlug } = useParams();
const [importOpened, { open: openImportModal, close: closeImportModal }] =
@@ -214,15 +233,24 @@ function SpaceMenu({ spaceId, onSpaceSettings }: SpaceMenuProps) {
const [exportOpened, { open: openExportModal, close: closeExportModal }] =
useDisclosure(false);
const { data: watchStatus } = useSpaceWatchStatusQuery(spaceId);
const watchMutation = useWatchSpaceMutation();
const unwatchMutation = useUnwatchSpaceMutation();
const isWatching = watchStatus?.watching ?? false;
const handleToggleWatch = () => {
if (isWatching) {
unwatchMutation.mutate(spaceId);
} else {
watchMutation.mutate(spaceId);
}
};
return (
<>
<Menu width={200} shadow="md" withArrow>
<Menu.Target>
<Tooltip
label={t("Import pages & space settings")}
withArrow
position="top"
>
<Tooltip label={t("Space menu")} withArrow position="top">
<ActionIcon
variant="default"
size={18}
@@ -235,50 +263,69 @@ function SpaceMenu({ spaceId, onSpaceSettings }: SpaceMenuProps) {
<Menu.Dropdown>
<Menu.Item
onClick={openImportModal}
leftSection={<IconArrowDown size={16} />}
onClick={handleToggleWatch}
leftSection={
isWatching ? <IconEyeOff size={16} /> : <IconEye size={16} />
}
>
{t("Import pages")}
{isWatching ? t("Stop watching space") : t("Watch space")}
</Menu.Item>
<Menu.Item
onClick={openExportModal}
leftSection={<IconFileExport size={16} />}
>
{t("Export space")}
</Menu.Item>
{canManagePages && (
<>
<Menu.Divider />
<Menu.Divider />
<Menu.Item
onClick={openImportModal}
leftSection={<IconArrowDown size={16} />}
>
{t("Import pages")}
</Menu.Item>
<Menu.Item
onClick={onSpaceSettings}
leftSection={<IconSettings size={16} />}
>
{t("Space settings")}
</Menu.Item>
<Menu.Item
onClick={openExportModal}
leftSection={<IconFileExport size={16} />}
>
{t("Export space")}
</Menu.Item>
<Menu.Item
component={Link}
to={`/s/${spaceSlug}/trash`}
leftSection={<IconTrash size={16} />}
>
{t("Trash")}
</Menu.Item>
<Menu.Divider />
<Menu.Item
onClick={onSpaceSettings}
leftSection={<IconSettings size={16} />}
>
{t("Space settings")}
</Menu.Item>
<Menu.Item
component={Link}
to={`/s/${spaceSlug}/trash`}
leftSection={<IconTrash size={16} />}
>
{t("Trash")}
</Menu.Item>
</>
)}
</Menu.Dropdown>
</Menu>
<PageImportModal
spaceId={spaceId}
open={importOpened}
onClose={closeImportModal}
/>
{canManagePages && (
<>
<PageImportModal
spaceId={spaceId}
open={importOpened}
onClose={closeImportModal}
/>
<ExportModal
type="space"
id={spaceId}
open={exportOpened}
onClose={closeExportModal}
/>
<ExportModal
type="space"
id={spaceId}
open={exportOpened}
onClose={closeExportModal}
/>
</>
)}
</>
);
}