Allow opening workspace if sync dir not empty

This commit is contained in:
Gregory Schier
2025-02-25 06:54:30 -08:00
parent 2db72fe6ef
commit 7af8c95fea
5 changed files with 48 additions and 24 deletions

View File

@@ -1,20 +1,11 @@
import { open } from '@tauri-apps/plugin-dialog';
import { applySync, calculateSyncFsOnly } from '@yaakapp-internal/sync';
import { createFastMutation } from '../hooks/useFastMutation';
import { showSimpleAlert } from '../lib/alert';
import { router } from '../lib/router';
export const openWorkspaceFromSyncDir = createFastMutation<void>({
export const openWorkspaceFromSyncDir = createFastMutation<void, void, string>({
mutationKey: [],
mutationFn: async () => {
const dir = await open({
title: 'Select Workspace Directory',
directory: true,
multiple: false,
});
if (dir == null) return;
mutationFn: async (dir) => {
const ops = await calculateSyncFsOnly(dir);
const workspace = ops

View File

@@ -20,7 +20,7 @@ export function CreateWorkspaceDialog({ hide }: Props) {
const [syncConfig, setSyncConfig] = useState<{
filePath: string | null;
initGit?: boolean;
}>({ filePath: null, initGit: true });
}>({ filePath: null, initGit: false });
return (
<VStack
@@ -62,8 +62,8 @@ export function CreateWorkspaceDialog({ hide }: Props) {
<SyncToFilesystemSetting
onChange={setSyncConfig}
onCreateNewWorkspace={hide}
value={syncConfig}
allowNonEmptyDirectory // Will do initial import when the workspace is created
/>
<Button type="submit" color="primary" className="ml-auto mt-3">
Create Workspace

View File

@@ -1,33 +1,54 @@
import { readDir } from '@tauri-apps/plugin-fs';
import { useState } from 'react';
import { openWorkspaceFromSyncDir } from '../commands/openWorkspaceFromSyncDir';
import { Banner } from './core/Banner';
import { Button } from './core/Button';
import { Checkbox } from './core/Checkbox';
import { VStack } from './core/Stacks';
import { SelectFile } from './SelectFile';
export interface SyncToFilesystemSettingProps {
onChange: (args: { filePath: string | null; initGit?: boolean }) => void;
onCreateNewWorkspace: () => void;
value: { filePath: string | null; initGit?: boolean };
allowNonEmptyDirectory?: boolean;
forceOpen?: boolean;
}
export function SyncToFilesystemSetting({
onChange,
onCreateNewWorkspace,
value,
allowNonEmptyDirectory,
forceOpen,
}: SyncToFilesystemSettingProps) {
const [error, setError] = useState<string | null>(null);
const [isNonEmpty, setIsNonEmpty] = useState<string | null>(null);
return (
<details open={forceOpen || !!value.filePath} className="w-full">
<summary>Data directory {typeof value.initGit === 'boolean' && ' and Git'}</summary>
<VStack className="my-2" space={3}>
<Banner color="info">
Sync workspace data to folder as plain text files, ideal for backup and Git collaboration.
Environments are excluded in order to keep your secrets private.
</Banner>
{error && <div className="text-danger">{error}</div>}
{isNonEmpty ? (
<Banner color="notice" className="flex flex-col gap-1.5">
<p>The selected directory must be empty. Did you want to open it instead?</p>
<div>
<Button
variant="border"
color="notice"
size="xs"
type="button"
onClick={() => {
openWorkspaceFromSyncDir.mutate(isNonEmpty);
onCreateNewWorkspace();
}}
>
Open Workspace
</Button>
</div>
</Banner>
) : (
<Banner color="info">
Sync workspace data to folder as plain text files, ideal for backup and Git
collaboration. Environments are excluded in order to keep your secrets private.
</Banner>
)}
<SelectFile
directory
@@ -37,12 +58,13 @@ export function SyncToFilesystemSetting({
onChange={async ({ filePath }) => {
if (filePath != null) {
const files = await readDir(filePath);
if (files.length > 0 && !allowNonEmptyDirectory) {
setError('The directory must be empty');
if (files.length > 0) {
setIsNonEmpty(filePath);
return;
}
}
setIsNonEmpty(null);
onChange({ ...value, filePath });
}}
/>

View File

@@ -1,3 +1,4 @@
import {open} from "@tauri-apps/plugin-dialog";
import { revealItemInDir } from '@tauri-apps/plugin-opener';
import classNames from 'classnames';
import { memo, useCallback, useMemo } from 'react';
@@ -75,7 +76,16 @@ export const WorkspaceActionsDropdown = memo(function WorkspaceActionsDropdown({
{
label: 'Open Existing Workspace',
leftSlot: <Icon icon="folder_open" />,
onSelect: openWorkspaceFromSyncDir.mutate,
onSelect: async () => {
const dir = await open({
title: 'Select Workspace Directory',
directory: true,
multiple: false,
});
if (dir == null) return;
openWorkspaceFromSyncDir.mutate(dir);
},
},
];

View File

@@ -63,6 +63,7 @@ export function WorkspaceSettingsDialog({ workspaceId, hide, openSyncMenu }: Pro
<SyncToFilesystemSetting
value={{ filePath: workspaceMeta.settingSyncDir }}
forceOpen={openSyncMenu}
onCreateNewWorkspace={hide}
onChange={({ filePath }) => {
upsertWorkspaceMeta.mutate({ ...workspaceMeta, settingSyncDir: filePath });
}}