extract open new project modal

This commit is contained in:
Nikita Galaiko 2023-05-09 13:53:59 +02:00
parent a47b0dda1f
commit 3fcdaa2104
8 changed files with 80 additions and 75 deletions

View File

@ -11,7 +11,6 @@
import type Events from '$lib/events';
export let projects: Readable<Project[]>;
export let addProject: (params: { path: string }) => Promise<Project>;
export let project = readable<Project | undefined>(undefined);
export let events: ReturnType<typeof Events>;
@ -26,7 +25,6 @@
selectedGroup !== undefined
? [selectedGroup]
: listAvailableCommands({
addProject,
projects,
project: scopeToProject ? project : undefined,
input,

View File

@ -1,7 +1,5 @@
import { type Project, git } from '$lib/api';
import { open } from '@tauri-apps/api/dialog';
import type Events from '$lib/events';
import { toasts } from '$lib';
import {
IconGitCommit,
IconFile,
@ -49,11 +47,11 @@ export type Group = {
};
const projectsGroup = ({
addProject,
events,
projects,
input
}: {
addProject: (params: { path: string }) => Promise<Project>;
events: ReturnType<typeof Events>;
projects: Project[];
input: string;
}): Group => ({
@ -63,21 +61,7 @@ const projectsGroup = ({
title: 'New project...',
hotkey: 'Meta+Shift+N',
icon: IconFile,
action: async () => {
const selectedPath = await open({
directory: true,
recursive: true
});
if (selectedPath === null) return;
if (Array.isArray(selectedPath) && selectedPath.length !== 1) return;
const projectPath = Array.isArray(selectedPath) ? selectedPath[0] : selectedPath;
try {
addProject({ path: projectPath });
} catch (e: any) {
toasts.error(e.message);
}
}
action: () => events.emit('openNewProjectModal')
},
...projects
.filter(
@ -235,18 +219,17 @@ const supportGroup = ({ input }: { input: string }): Group => ({
});
export default (params: {
addProject: (params: { path: string }) => Promise<Project>;
projects: Project[];
project?: Project;
input: string;
events: ReturnType<typeof Events>;
}) => {
const { addProject, projects, input, project, events } = params;
const { projects, input, project, events } = params;
const groups = [];
groups.push(commandsGroup({ project, input, events }));
groups.push(navigateGroup({ project, input }));
!project && groups.push(projectsGroup({ addProject, projects, input }));
!project && groups.push(projectsGroup({ events, projects, input }));
project && groups.push(fileGroup({ project, input }));
groups.push(supportGroup({ input }));

View File

@ -0,0 +1,20 @@
<script lang="ts">
import { open } from '@tauri-apps/api/dialog';
import { toasts, api } from '$lib';
export let projects: ReturnType<typeof api.projects.Projects>;
export const show = () =>
open({ directory: true, recursive: true })
.then((selectedPath) => {
if (selectedPath === null) return;
if (Array.isArray(selectedPath) && selectedPath.length !== 1) return;
const projectPath = Array.isArray(selectedPath) ? selectedPath[0] : selectedPath;
return projects
.add({ path: projectPath })
.then(() => toasts.success('Project added successfully'));
})
.catch((e: any) => {
toasts.error(e.message);
});
</script>

View File

@ -12,3 +12,4 @@ export { default as Statuses } from './Statuses.svelte';
export { default as Differ } from './Differ';
export { default as DeltasViewer } from './DeltasViewer.svelte';
export { default as DiffContext } from './DiffContext.svelte';
export { default as OpenNewProjectModal } from './OpenNewProjectModal.svelte';

1
src/lib/stores/index.ts Normal file
View File

@ -0,0 +1 @@
export * as projects from './projects';

View File

@ -0,0 +1,33 @@
import { asyncWritable, derived } from '@square/svelte-store';
import { api } from '$lib';
const store = asyncWritable([], api.projects.list);
export const list = () => store;
export const get = (id: string) => derived(store, (projects) => projects.find((p) => p.id === id));
export const update = async (project: { id: string; title?: string; api?: api.Project['api'] }) => {
const updated = await api.projects.update({ project });
store.update((projects) => {
const index = projects.findIndex((p) => p.id === project.id);
if (index === -1) {
return [...projects, updated];
} else {
projects[index] = updated;
return projects;
}
});
return updated;
};
export const del = async (project: { id: string }) => {
await api.projects.del(project);
store.update((projects) => projects.filter((p) => p.id !== project.id));
};
export const add = async (params: { path: string }) => {
const project = await api.projects.add(params);
store.update((projects) => [...projects, project]);
return project;
};

View File

@ -1,10 +1,15 @@
<script lang="ts">
import '../app.postcss';
import { open } from '@tauri-apps/api/dialog';
import { toasts, Toaster } from '$lib';
import { Toaster } from '$lib';
import type { LayoutData } from './$types';
import { BackForwardButtons, Link, CommandPalette, Breadcrumbs } from '$lib/components';
import {
BackForwardButtons,
Link,
CommandPalette,
Breadcrumbs,
OpenNewProjectModal
} from '$lib/components';
import { page } from '$app/stores';
import { derived } from '@square/svelte-store';
import { onMount } from 'svelte';
@ -13,43 +18,29 @@
export let data: LayoutData;
const { user, posthog, projects, sentry, events, hotkeys } = data;
$: console.log($user);
const project = derived([page, projects], ([page, projects]) =>
projects?.find((project) => project.id === page.params.projectId)
);
let commandPalette: CommandPalette;
let openNewProjectModal: OpenNewProjectModal;
onMount(() =>
unsubscribe(
events.on('openNewProjectModal', async () => {
const selectedPath = await open({
directory: true,
recursive: true
});
if (selectedPath === null) return;
if (Array.isArray(selectedPath) && selectedPath.length !== 1) return;
const projectPath = Array.isArray(selectedPath) ? selectedPath[0] : selectedPath;
try {
await projects.add({ path: projectPath });
} catch (e: any) {
toasts.error(e.message);
}
}),
events.on('openNewProjectModal', () => openNewProjectModal?.show()),
events.on('openCommandPalette', () => commandPalette?.show()),
events.on('closeCommandPalette', () => commandPalette?.close()),
events.on('goto', (path: string) => goto(path)),
hotkeys.on('Meta+k', () => events.emit('openCommandPalette')),
hotkeys.on('Meta+,', () => events.emit('goto', '/users/')),
hotkeys.on('Meta+Shift+N', () => events.emit('openNewProjectModal'))
hotkeys.on('Meta+Shift+N', () => events.emit('openNewProjectModal')),
user.subscribe(posthog.identify),
user.subscribe(sentry.identify)
)
);
user.subscribe(posthog.identify);
user.subscribe(sentry.identify);
</script>
<div class="flex h-full max-h-full min-h-full flex-col">
@ -85,12 +76,8 @@
</div>
<Toaster />
{#await Promise.all([projects.load(), project.load()]) then}
<CommandPalette
bind:this={commandPalette}
{projects}
{project}
addProject={projects.add}
{events}
/>
<CommandPalette bind:this={commandPalette} {projects} {project} {events} />
{/await}
</div>
<OpenNewProjectModal bind:this={openNewProjectModal} {projects} />

View File

@ -1,28 +1,10 @@
<script lang="ts">
import type { LayoutData } from './$types';
import { open } from '@tauri-apps/api/dialog';
import { toasts } from '$lib';
import { Button, Tooltip } from '$lib/components';
export let data: LayoutData;
const { projects } = data;
const onAddLocalRepositoryClick = async () => {
const selectedPath = await open({
directory: true,
recursive: true
});
if (selectedPath === null) return;
if (Array.isArray(selectedPath) && selectedPath.length !== 1) return;
const projectPath = Array.isArray(selectedPath) ? selectedPath[0] : selectedPath;
try {
await projects.add({ path: projectPath });
} catch (e: any) {
toasts.error(e.message);
}
};
const { projects, events } = data;
</script>
<div class="h-full w-full p-8">
@ -142,7 +124,7 @@
<h3 class="mt-2 text-lg font-semibold text-zinc-300">No projects</h3>
<p class="mt-1 text-gray-500">Get started by tracking a project you're working on.</p>
<div class="mt-6">
<Button color="primary" on:click={onAddLocalRepositoryClick}>
<Button color="primary" on:click={() => events.emit('openNewProjectModal')}>
Start Tracking a Project
</Button>
</div>
@ -160,7 +142,7 @@
</div>
<div>
<Tooltip label="Adds a git repository on your computer to GitButler">
<Button color="primary" on:click={onAddLocalRepositoryClick}>
<Button color="primary" on:click={() => events.emit('openNewProjectModal')}>
Track a New Project
</Button>
</Tooltip>