Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic sync backfill dialog #2405

Merged
merged 5 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/api/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub(crate) fn mount() -> AlphaRouter<Ctx> {
.await?)
})
})
.procedure("enable", {
.procedure("backfill", {
R.with2(library())
.mutation(|(node, library), _: ()| async move {
if library
Expand Down
49 changes: 39 additions & 10 deletions interface/app/$libraryId/debug/sync.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { useMemo } from 'react';
import { useEffect, useMemo } from 'react';
import {
CRDTOperation,
CRDTOperationData,
useLibraryMutation,
useLibraryQuery,
useLibrarySubscription
useLibrarySubscription,
useZodForm
} from '@sd/client';
import { Button } from '@sd/ui';
import { Button, Dialog, dialogManager, useDialog, UseDialogProps, z } from '@sd/ui';
import { useRouteTitle } from '~/hooks/useRouteTitle';

type MessageGroup = {
Expand All @@ -21,7 +22,7 @@ export const Component = () => {
const syncEnabled = useLibraryQuery(['sync.enabled']);

const messages = useLibraryQuery(['sync.messages']);
const enableSync = useLibraryMutation(['sync.enable'], {
const backfillSync = useLibraryMutation(['sync.backfill'], {
onSuccess: async () => {
await syncEnabled.refetch();
await messages.refetch();
Expand All @@ -32,18 +33,17 @@ export const Component = () => {
onData: () => messages.refetch()
});

const groups = useMemo(
() => (messages.data && calculateGroups(messages.data)) || [],
[messages]
);
const groups = useMemo(() => (messages.data && calculateGroups(messages.data)) || [], [messages]);

return (
<ul className="space-y-4 p-4">
{!syncEnabled.data && (
<Button
variant="accent"
onClick={() => enableSync.mutate(null)}
disabled={enableSync.isLoading}
onClick={() => {
dialogManager.create((dialogProps) => <SyncBackfillDialog {...dialogProps} />);
}}
disabled={backfillSync.isLoading}
>
Enable sync messages
</Button>
Expand Down Expand Up @@ -127,3 +127,32 @@ function calculateGroups(messages: CRDTOperation[]) {
return acc;
}, []);
}

function SyncBackfillDialog(props: UseDialogProps) {
const form = useZodForm({ schema: z.object({}) });
const dialog = useDialog(props);

const enableSync = useLibraryMutation(['sync.backfill'], {});

// dialog is in charge of enabling sync
useEffect(() => {
form.handleSubmit(
async () => {
await enableSync.mutateAsync(null).then(() => (dialog.state.open = false));
},
() => {}
)();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<Dialog
title="Backfilling Sync Operations"
description="Library is paused until backfill completes"
form={form}
dialog={dialog}
hideButtons
ignoreClickOutside
/>
);
}
2 changes: 1 addition & 1 deletion packages/client/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export type Procedures = {
{ key: "search.saved.create", input: LibraryArgs<{ name: string; target?: SearchTarget; search?: string | null; filters?: string | null; description?: string | null; icon?: string | null }>, result: null } |
{ key: "search.saved.delete", input: LibraryArgs<number>, result: null } |
{ key: "search.saved.update", input: LibraryArgs<[number, Args]>, result: null } |
{ key: "sync.enable", input: LibraryArgs<null>, result: null } |
{ key: "sync.backfill", input: LibraryArgs<null>, result: null } |
{ key: "tags.assign", input: LibraryArgs<{ targets: Target[]; tag_id: number; unassign: boolean }>, result: null } |
{ key: "tags.create", input: LibraryArgs<TagCreateArgs>, result: Tag } |
{ key: "tags.delete", input: LibraryArgs<number>, result: null } |
Expand Down
49 changes: 26 additions & 23 deletions packages/ui/src/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ export interface DialogProps<S extends FieldValues>
errorMessageException?: string; //this is to bypass a specific form error message if it starts with a specific string
formClassName?: string;
icon?: ReactNode;
hideButtons?: boolean;
ignoreClickOutside?: boolean;
}

export function Dialog<S extends FieldValues>({
Expand Down Expand Up @@ -269,6 +271,7 @@ export function Dialog<S extends FieldValues>({
<AnimatedDialogContent
className="!pointer-events-none fixed inset-0 z-50 grid place-items-center overflow-y-auto"
style={styles}
onInteractOutside={(e) => props.ignoreClickOutside && e.preventDefault()}
>
<Form
form={form}
Expand Down Expand Up @@ -302,30 +305,30 @@ export function Dialog<S extends FieldValues>({
)}
>
{form.formState.isSubmitting && <Loader />}
{props.buttonsSideContent && (
<div>{props.buttonsSideContent}</div>
)}
{props.buttonsSideContent && <div>{props.buttonsSideContent}</div>}
<div className="grow" />
<div
className={clsx(
invertButtonFocus ? 'flex-row-reverse' : ' flex-row',
'flex gap-2'
)}
>
{invertButtonFocus ? (
<>
{submitButton}
{props.cancelBtn && cancelButton}
{onCancelled && closeButton}
</>
) : (
<>
{onCancelled && closeButton}
{props.cancelBtn && cancelButton}
{submitButton}
</>
)}
</div>
{!props.hideButtons && (
<div
className={clsx(
invertButtonFocus ? 'flex-row-reverse' : ' flex-row',
'flex gap-2'
)}
>
{invertButtonFocus ? (
<>
{submitButton}
{props.cancelBtn && cancelButton}
{onCancelled && closeButton}
</>
) : (
<>
{onCancelled && closeButton}
{props.cancelBtn && cancelButton}
{submitButton}
</>
)}
</div>
)}
</div>
</Form>
<Remover id={dialog.id} />
Expand Down
Loading