mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-02 07:53:55 +03:00
extract open new project modal
This commit is contained in:
parent
a47b0dda1f
commit
3fcdaa2104
@ -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,
|
||||
|
@ -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 }));
|
||||
|
||||
|
20
src/lib/components/OpenNewProjectModal.svelte
Normal file
20
src/lib/components/OpenNewProjectModal.svelte
Normal 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>
|
@ -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
1
src/lib/stores/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * as projects from './projects';
|
33
src/lib/stores/projects.ts
Normal file
33
src/lib/stores/projects.ts
Normal 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;
|
||||
};
|
@ -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} />
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user