-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #144 from briefercloud/unexecuted-blocks-setting
add setting to control whether to run previous unexecuted blocks
- Loading branch information
Showing
11 changed files
with
281 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
apps/api/src/v1/workspaces/workspace/documents/document/settings.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { Router } from 'express' | ||
import { getParam } from '../../../../../utils/express.js' | ||
import { z } from 'zod' | ||
import { IOServer } from '../../../../../websocket/index.js' | ||
import prisma, { recoverFromNotFound } from '@briefer/database' | ||
import { broadcastDocument } from '../../../../../websocket/workspace/documents.js' | ||
|
||
const DocumentSettings = z.object({ | ||
runUnexecutedBlocks: z.boolean(), | ||
}) | ||
|
||
export default function settingsRouter(socketServer: IOServer) { | ||
const settingsRouter = Router({ mergeParams: true }) | ||
|
||
settingsRouter.put('/', async (req, res) => { | ||
const workspaceId = getParam(req, 'workspaceId') | ||
const documentId = getParam(req, 'documentId') | ||
const body = DocumentSettings.safeParse(req.body) | ||
if (!body.success) { | ||
res.status(400).json({ reason: 'invalid-payload' }) | ||
return | ||
} | ||
|
||
const runUnexecutedBlocks = body.data.runUnexecutedBlocks | ||
|
||
try { | ||
const doc = await recoverFromNotFound( | ||
prisma().document.update({ | ||
where: { id: documentId }, | ||
data: { runUnexecutedBlocks }, | ||
}) | ||
) | ||
if (!doc) { | ||
res.status(404).end() | ||
return | ||
} | ||
|
||
await broadcastDocument(socketServer, workspaceId, documentId) | ||
|
||
res.sendStatus(204) | ||
} catch (err) { | ||
req.log.error( | ||
{ | ||
workspaceId, | ||
documentId, | ||
err, | ||
}, | ||
'Failed to update document settings' | ||
) | ||
res.status(500).end() | ||
} | ||
}) | ||
|
||
return settingsRouter | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import * as Y from 'yjs' | ||
import { useState } from 'react' | ||
import { Switch } from '@headlessui/react' | ||
import { ChevronDoubleRightIcon } from '@heroicons/react/24/outline' | ||
import { Transition } from '@headlessui/react' | ||
import clsx from 'clsx' | ||
import useDocument from '@/hooks/useDocument' | ||
|
||
interface Props { | ||
workspaceId: string | ||
documentId: string | ||
visible: boolean | ||
onHide: () => void | ||
yDoc?: Y.Doc | ||
} | ||
|
||
export default function PageSettingsPanel(props: Props) { | ||
const [{ document }, api] = useDocument(props.workspaceId, props.documentId) | ||
|
||
console.log('runUnexecutedBlocks', document?.runUnexecutedBlocks) | ||
return ( | ||
<> | ||
<Transition | ||
as="div" | ||
show={props.visible} | ||
className="top-0 right-0 h-full absolute bg-white z-30" | ||
enter="transition-transform duration-300" | ||
enterFrom="transform translate-x-full" | ||
enterTo="transform translate-x-0" | ||
leave="transition-transform duration-300" | ||
leaveFrom="transform translate-x-0" | ||
leaveTo="transform translate-x-full" | ||
> | ||
<button | ||
className="absolute z-10 top-7 transform rounded-full border border-gray-300 text-gray-400 bg-white hover:bg-gray-100 w-6 h-6 flex justify-center items-center left-0 -translate-x-1/2" | ||
onClick={props.onHide} | ||
> | ||
<ChevronDoubleRightIcon className="w-3 h-3" /> | ||
</button> | ||
<div className="w-[324px] flex flex-col border-l border-gray-200 h-full bg-white"> | ||
<div className="flex justify-between border-b p-6 space-x-3"> | ||
<div> | ||
<h3 className="text-lg font-medium leading-6 text-gray-900 pr-1.5"> | ||
Page settings | ||
</h3> | ||
<p className="text-gray-500 text-sm pt-1"> | ||
{ | ||
"Configure this page's behavior and default visualization mode." | ||
} | ||
</p> | ||
</div> | ||
</div> | ||
<div className="h-full w-full px-6"> | ||
<PageSettingToggle | ||
name="Auto-run pending blocks" | ||
description="Whether Briefer should automatically run unexecuted preceding blocks when a block is executed." | ||
enabled={document?.runUnexecutedBlocks ?? false} | ||
onToggle={api.toggleRunUnexecutedBlocks} | ||
/> | ||
</div> | ||
</div> | ||
</Transition> | ||
</> | ||
) | ||
} | ||
|
||
type PageSettingToggleProps = { | ||
name: string | ||
description: string | ||
enabled: boolean | ||
onToggle: () => void | ||
disabled?: boolean | ||
} | ||
|
||
export function PageSettingToggle(props: PageSettingToggleProps) { | ||
return ( | ||
<Switch.Group | ||
as="div" | ||
className="flex flex-col items-center justify-between py-4 gap-x-16 gap-y-2" | ||
> | ||
<span className="flex flex-grow items-center justify-between w-full"> | ||
<Switch.Label | ||
as="span" | ||
className="text-sm font-medium leading-6 text-gray-900" | ||
passive | ||
> | ||
{props.name} | ||
</Switch.Label> | ||
<Switch | ||
checked={props.enabled} | ||
onChange={props.onToggle} | ||
className={clsx( | ||
props.enabled ? 'bg-primary-600' : 'bg-gray-200', | ||
'relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary-600 focus:ring-offset-2' | ||
)} | ||
disabled={props.disabled} | ||
> | ||
<span | ||
aria-hidden="true" | ||
className={clsx( | ||
props.enabled ? 'translate-x-5' : 'translate-x-0', | ||
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out' | ||
)} | ||
/> | ||
</Switch> | ||
</span> | ||
<span className="text-sm text-gray-500">{props.description}</span> | ||
</Switch.Group> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.