feat(git-sync): independent toggles for project files and PDF push
Build and Deploy Verso / deploy (push) Successful in 12m48s

Two new boolean fields on the project (gitSyncPushFiles, gitSyncPushPdf,
both default true) let users control what gets pushed independently:
- "Push project files" switch — skip all docs/binary files when off
- "Push compiled PDF" switch — grayed out when no pdfPath is set

The push button and auto-push are disabled when both switches would
result in nothing being pushed. Config is stored in MongoDB so settings
persist per-project.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
claude
2026-06-23 23:21:37 +00:00
co-authored by Claude Sonnet 4.6
parent 9a474f7790
commit be8aef44fe
10 changed files with 92 additions and 31 deletions
@@ -25,6 +25,8 @@ export default function GitSyncWidget() {
const [remoteUrl, setRemoteUrl] = useState(getMeta('ol-gitRemote') ?? '')
const [subPath, setSubPath] = useState(getMeta('ol-gitSyncPath') ?? '')
const [pdfPath, setPdfPath] = useState(getMeta('ol-gitSyncPdfPath') ?? '')
const [pushFiles, setPushFiles] = useState(getMeta('ol-gitSyncPushFiles') ?? true)
const [pushPdf, setPushPdf] = useState(getMeta('ol-gitSyncPushPdf') ?? true)
const [autoPush, setAutoPush] = useState(
() => localStorage.getItem(AUTO_PUSH_KEY) === 'true'
)
@@ -35,7 +37,6 @@ export default function GitSyncWidget() {
const wasCompilingRef = useRef(false)
const isBusyRef = useRef(false)
// Keep isBusyRef in sync so the compile watcher can check it
useEffect(() => {
isBusyRef.current = status === 'busy'
}, [status])
@@ -58,7 +59,7 @@ export default function GitSyncWidget() {
async function saveConfig() {
await postJSON(`/project/${projectId}/git-sync`, {
body: { remoteUrl, subPath, pdfPath },
body: { remoteUrl, subPath, pdfPath, pushFiles, pushPdf },
})
}
@@ -121,6 +122,7 @@ export default function GitSyncWidget() {
}
const isBusy = status === 'busy'
const nothingToPush = !pushFiles && (!pushPdf || !pdfPath.trim())
return (
<div className="git-sync-widget">
@@ -153,6 +155,17 @@ export default function GitSyncWidget() {
/>
</OLFormGroup>
<OLFormGroup controlId="git-sync-push-files">
<FormCheck
type="switch"
id="git-sync-push-files"
label={t('git_sync_push_files')}
checked={pushFiles}
onChange={e => setPushFiles(e.target.checked)}
disabled={isBusy}
/>
</OLFormGroup>
<OLFormGroup controlId="git-sync-pdf-path">
<OLFormLabel>{t('git_sync_pdf_path')}</OLFormLabel>
<OLFormControl
@@ -164,6 +177,17 @@ export default function GitSyncWidget() {
/>
</OLFormGroup>
<OLFormGroup controlId="git-sync-push-pdf">
<FormCheck
type="switch"
id="git-sync-push-pdf"
label={t('git_sync_push_pdf')}
checked={pushPdf}
onChange={e => setPushPdf(e.target.checked)}
disabled={isBusy || !pdfPath.trim()}
/>
</OLFormGroup>
<OLFormGroup controlId="git-sync-auto-push">
<FormCheck
type="switch"
@@ -171,7 +195,7 @@ export default function GitSyncWidget() {
label={t('git_sync_auto_push_on_compile')}
checked={autoPush}
onChange={handleAutoPushToggle}
disabled={isBusy || !remoteUrl.trim()}
disabled={isBusy || !remoteUrl.trim() || nothingToPush}
/>
</OLFormGroup>
@@ -191,7 +215,7 @@ export default function GitSyncWidget() {
variant="primary"
size="sm"
onClick={handlePush}
disabled={isBusy || !remoteUrl.trim()}
disabled={isBusy || !remoteUrl.trim() || nothingToPush}
isLoading={isBusy && lastAction === 'push'}
loadingLabel={t('git_sync_pushing')}
>