Skip to content
File

Blob: src/client/components/workspace/share-dialog/controller.ts

typescript109 lines
1import { useCallback, useMemo, useState } from "react";
2 
3import { useWorkspaceRole } from "@/client/components/workspace/use-workspace-view";
4import { deriveSitePublishAffordance } from "@/client/lib/affordance/site-publish";
5import { useOnline } from "@/client/hooks/use-online";
6import { useAuthStore } from "@/client/stores/auth-store";
7import { getSitePublishingEntitlements } from "@/shared/entitlements";
8 
9import { useShareController } from "./share-controller";
10import { useSitePublishController } from "./site-publish-controller";
11import type { DialogTab, ShareDialogProps, ShareDialogShellValue, ShareDialogSlices, WorkspaceRole } from "./types";
12 
13export function useShareDialogController({
14 pageId,
15 workspaceId,
16 pageKind,
17 disabled,
18 title,
19}: ShareDialogProps): ShareDialogSlices {
20 const [open, setOpen] = useState(false);
21 const [activeTab, setActiveTab] = useState<DialogTab>("share");
22 const user = useAuthStore((s) => s.user);
23 const online = useOnline();
24 const workspaceRole: WorkspaceRole = useWorkspaceRole() ?? "none";
25 const currentUserId = user?.id;
26 
27 const share = useShareController({
28 pageId,
29 disabled,
30 open,
31 workspaceRole,
32 online,
33 currentUserId,
34 });
35 
36 const siteEntitlements = getSitePublishingEntitlements(workspaceRole);
37 const publish = useSitePublishController({
38 pageId,
39 workspaceId,
40 pageKind,
41 canManageSite: siteEntitlements.manageSite,
42 canViewPagePublishStatus: siteEntitlements.viewPagePublishStatus,
43 open: open && !disabled,
44 });
45 
46 const publishAffordance = useMemo(
47 () =>
48 deriveSitePublishAffordance({
49 entitlements: siteEntitlements,
50 online,
51 pageKind,
52 }),
53 [siteEntitlements, online, pageKind],
54 );
55 
56 const close = useCallback(() => {
57 setOpen(false);
58 share.people.dismissSuggestions();
59 }, [share.people]);
60 
61 const toggleOpen = useCallback(() => {
62 if (disabled) return;
63 if (!open) {
64 share.resetTransient();
65 }
66 setOpen((current) => !current);
67 }, [disabled, open, share]);
68 
69 const shell = useMemo<ShareDialogShellValue>(
70 () => ({
71 disabled: disabled ?? false,
72 title,
73 open,
74 loading: share.loading,
75 creating: share.creating,
76 error: share.error,
77 dialogAffordance: share.dialogAffordance,
78 publishAffordance,
79 workspaceRole,
80 online,
81 currentUserId,
82 activeTab,
83 setActiveTab,
84 toggleOpen,
85 close,
86 deleteShare: share.deleteShare,
87 }),
88 [
89 disabled,
90 title,
91 open,
92 share.loading,
93 share.creating,
94 share.error,
95 share.dialogAffordance,
96 share.deleteShare,
97 publishAffordance,
98 workspaceRole,
99 online,
100 currentUserId,
101 activeTab,
102 toggleOpen,
103 close,
104 ],
105 );
106 
107 return { shell, people: share.people, link: share.link, publish };
108}