From dc24fea23b1890a2131a7e54583dcc611eba3271 Mon Sep 17 00:00:00 2001 From: Lucas Fernandes da Costa Date: Sat, 4 Jan 2025 17:44:07 -0300 Subject: [PATCH] allow share links with collapsible sidebar param --- .../workspace/documents/document/settings.ts | 10 +++++-- apps/web/src/components/Dashboard/index.tsx | 12 +++++++-- apps/web/src/components/PageSettingsPanel.tsx | 6 +++++ .../src/components/PrivateDocumentPage.tsx | 11 +++++++- apps/web/src/hooks/useDocument.ts | 26 ++++++++++++++++++- apps/web/src/hooks/useDocuments.tsx | 7 ++++- apps/web/src/hooks/useSideBar.tsx | 4 ++- docs/settings/page-settings.mdx | 10 +++++++ .../migration.sql | 2 ++ packages/database/prisma/schema.prisma | 17 ++++++------ 10 files changed, 89 insertions(+), 16 deletions(-) create mode 100644 packages/database/prisma/migrations/20250104200947_share_links_without_sidebar/migration.sql diff --git a/apps/api/src/v1/workspaces/workspace/documents/document/settings.ts b/apps/api/src/v1/workspaces/workspace/documents/document/settings.ts index e206daaf..c1867c98 100644 --- a/apps/api/src/v1/workspaces/workspace/documents/document/settings.ts +++ b/apps/api/src/v1/workspaces/workspace/documents/document/settings.ts @@ -8,6 +8,7 @@ import { broadcastDocument } from '../../../../../websocket/workspace/documents. const DocumentSettings = z.object({ runUnexecutedBlocks: z.boolean().optional(), runSQLSelection: z.boolean().optional(), + shareLinksWithoutSidebar: z.boolean().optional(), }) export default function settingsRouter(socketServer: IOServer) { @@ -22,13 +23,18 @@ export default function settingsRouter(socketServer: IOServer) { return } - const { runUnexecutedBlocks, runSQLSelection } = body.data + const { runUnexecutedBlocks, runSQLSelection, shareLinksWithoutSidebar } = + body.data try { const doc = await recoverFromNotFound( prisma().document.update({ where: { id: documentId }, - data: { runUnexecutedBlocks, runSQLSelection }, + data: { + runUnexecutedBlocks, + runSQLSelection, + shareLinksWithoutSidebar, + }, }) ) if (!doc) { diff --git a/apps/web/src/components/Dashboard/index.tsx b/apps/web/src/components/Dashboard/index.tsx index fab31c50..1cad0691 100644 --- a/apps/web/src/components/Dashboard/index.tsx +++ b/apps/web/src/components/Dashboard/index.tsx @@ -86,12 +86,20 @@ export default function Dashboard(props: Props) { ) }, [props.publish, props.publishing]) + const shareLinkWithoutSidebar = props.document.shareLinksWithoutSidebar const copyLink = useMemo( () => `${NEXT_PUBLIC_PUBLIC_URL()}/workspaces/${ props.document.workspaceId - }/documents/${props.document.id}`, - [router] + }/documents/${props.document.id}/dashboard${ + props.isEditing ? '/edit' : '' + }${shareLinkWithoutSidebar ? '?sidebarCollapsed=true' : ''}`, + [ + props.document.workspaceId, + props.document.id, + props.isEditing, + shareLinkWithoutSidebar, + ] ) const documentTitle = useMemo( diff --git a/apps/web/src/components/PageSettingsPanel.tsx b/apps/web/src/components/PageSettingsPanel.tsx index 60c517c5..92c95f86 100644 --- a/apps/web/src/components/PageSettingsPanel.tsx +++ b/apps/web/src/components/PageSettingsPanel.tsx @@ -61,6 +61,12 @@ export default function PageSettingsPanel(props: Props) { enabled={document?.runSQLSelection ?? false} onToggle={api.toggleRunSQLSelection} /> + diff --git a/apps/web/src/components/PrivateDocumentPage.tsx b/apps/web/src/components/PrivateDocumentPage.tsx index faee2b90..1a268ca3 100644 --- a/apps/web/src/components/PrivateDocumentPage.tsx +++ b/apps/web/src/components/PrivateDocumentPage.tsx @@ -165,12 +165,21 @@ function PrivateDocumentPageInner( }, [setSelectedSidebar]) const router = useRouter() + const shareLinkWithoutSidebar = props.document.shareLinksWithoutSidebar const copyLink = useMemo( () => `${NEXT_PUBLIC_PUBLIC_URL()}/workspaces/${props.workspaceId}/documents/${ props.documentId + }/notebook${props.isApp ? '' : '/edit'}${ + shareLinkWithoutSidebar ? `?sidebarCollapsed=true` : '' }`, - [router] + [ + router, + props.workspaceId, + props.documentId, + props.isApp, + shareLinkWithoutSidebar, + ] ) const isViewer = props.user.roles[props.workspaceId] === 'viewer' diff --git a/apps/web/src/hooks/useDocument.ts b/apps/web/src/hooks/useDocument.ts index 20c9075f..1716706a 100644 --- a/apps/web/src/hooks/useDocument.ts +++ b/apps/web/src/hooks/useDocument.ts @@ -7,6 +7,7 @@ type API = { publish: () => Promise toggleRunUnexecutedBlocks: () => Promise toggleRunSQLSelection: () => Promise + toggleShareLinksWithoutSidebar: () => Promise } type UseDocument = [ @@ -76,10 +77,32 @@ function useDocument(workspaceId: string, documentId: string): UseDocument { api.updateDocumentSettings, ]) + const toggleShareLinksWithoutSidebar = useCallback(async () => { + const newShareLinksWithoutSidebar = !document?.shareLinksWithoutSidebar + try { + await api.updateDocumentSettings(documentId, { + shareLinksWithoutSidebar: newShareLinksWithoutSidebar, + }) + } catch (err) { + alert('Failed to update document settings') + } + }, [ + workspaceId, + documentId, + document?.shareLinksWithoutSidebar, + api.updateDocumentSettings, + ]) + return useMemo( () => [ { document, loading, publishing }, - { setIcon, publish, toggleRunUnexecutedBlocks, toggleRunSQLSelection }, + { + setIcon, + publish, + toggleRunUnexecutedBlocks, + toggleRunSQLSelection, + toggleShareLinksWithoutSidebar, + }, ], [ loading, @@ -87,6 +110,7 @@ function useDocument(workspaceId: string, documentId: string): UseDocument { publish, toggleRunUnexecutedBlocks, toggleRunSQLSelection, + toggleShareLinksWithoutSidebar, ] ) } diff --git a/apps/web/src/hooks/useDocuments.tsx b/apps/web/src/hooks/useDocuments.tsx index 453555b1..62e46659 100644 --- a/apps/web/src/hooks/useDocuments.tsx +++ b/apps/web/src/hooks/useDocuments.tsx @@ -75,6 +75,7 @@ function upsertDocumentInMemory( userAppClock: {}, runUnexecutedBlocks: false, runSQLSelection: false, + shareLinksWithoutSidebar: true, hasDashboard: false, }) } @@ -207,7 +208,11 @@ type API = { ) => Promise updateDocumentSettings: ( id: string, - settings: { runUnexecutedBlocks?: boolean; runSQLSelection?: boolean } + settings: { + runUnexecutedBlocks?: boolean + runSQLSelection?: boolean + shareLinksWithoutSidebar?: boolean + } ) => Promise publish: (id: string) => Promise } diff --git a/apps/web/src/hooks/useSideBar.tsx b/apps/web/src/hooks/useSideBar.tsx index a823b06b..6c8ee880 100644 --- a/apps/web/src/hooks/useSideBar.tsx +++ b/apps/web/src/hooks/useSideBar.tsx @@ -5,6 +5,7 @@ import { useContext, useState, } from 'react' +import { useStringQuery } from './useQueryArgs' type Context = [boolean, Dispatch>] const Context = createContext([true, () => {}] as unknown as Context) @@ -14,7 +15,8 @@ export default function useSideBar(): Context { } export function SideBarProvider({ children }: { children: React.ReactNode }) { - const value = useState(true) + const noSidebarQs = useStringQuery('sidebarCollapsed') + const value = useState(noSidebarQs === 'true') return {children} } diff --git a/docs/settings/page-settings.mdx b/docs/settings/page-settings.mdx index bd2944d2..24f124a4 100644 --- a/docs/settings/page-settings.mdx +++ b/docs/settings/page-settings.mdx @@ -25,3 +25,13 @@ When you run a SQL block, Briefer will run its entire content by default. If you only want to run a specific part of the SQL block, you need to enable the "Run selected SQL only" switch. After enabling this setting, Briefer will only run the SQL code you've selected. If you haven't selected any code, Briefer will run the entire block. + +## Share links without sidebar + +By default, clicking the "copy link" element within the "Share" menu will copy a link that opens the page with the sidebar _collapsed_. + +If you want to share a link that opens the page with the sidebar _expanded_, you can disable the "Share links without sidebar" switch. + + + The query parameter which controls the sidebar state is `sidebarCollapsed`. You can also manually set it to `true` or `false` to control the sidebar state. + diff --git a/packages/database/prisma/migrations/20250104200947_share_links_without_sidebar/migration.sql b/packages/database/prisma/migrations/20250104200947_share_links_without_sidebar/migration.sql new file mode 100644 index 00000000..fef30362 --- /dev/null +++ b/packages/database/prisma/migrations/20250104200947_share_links_without_sidebar/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Document" ADD COLUMN "shareLinksWithoutSidebar" BOOLEAN NOT NULL DEFAULT true; diff --git a/packages/database/prisma/schema.prisma b/packages/database/prisma/schema.prisma index 2b858fc8..be5f2df2 100644 --- a/packages/database/prisma/schema.prisma +++ b/packages/database/prisma/schema.prisma @@ -29,16 +29,17 @@ model Document { parent Document? @relation("DocumentParent", fields: [parentId], references: [id], onDelete: Cascade) children Document[] @relation("DocumentParent") - yjsDocument YjsDocument? - yjsAppDocuments YjsAppDocument[] - comments Comment[] - Favorite Favorite[] - executionSchedules ExecutionSchedule[] - reusableComponents ReusableComponent[] + yjsDocument YjsDocument? + yjsAppDocuments YjsAppDocument[] + comments Comment[] + Favorite Favorite[] + executionSchedules ExecutionSchedule[] + reusableComponents ReusableComponent[] reusableComponentInstances ReusableComponentInstance[] - runUnexecutedBlocks Boolean @default(false) - runSQLSelection Boolean @default(false) + runUnexecutedBlocks Boolean @default(false) + runSQLSelection Boolean @default(false) + shareLinksWithoutSidebar Boolean @default(false) } model YjsDocument {