mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-09-11 12:25:42 +03:00
commit: connect api
This commit is contained in:
parent
7807296918
commit
831a9c606b
@ -1,2 +1,11 @@
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
|
||||
export { default as statuses } from './statuses';
|
||||
export { default as activity } from './activity';
|
||||
|
||||
export const commit = (params: {
|
||||
projectId: string;
|
||||
message: string;
|
||||
files: Array<string>;
|
||||
push: boolean;
|
||||
}) => invoke<boolean>('git_commit', params);
|
||||
|
@ -2,10 +2,16 @@
|
||||
import type { PageData } from './$types';
|
||||
import { collapsable } from '$lib/paths';
|
||||
import { derived, writable } from 'svelte/store';
|
||||
import { commit } from '$lib/git';
|
||||
import DiffViewer from '$lib/components/DiffViewer.svelte';
|
||||
import { error, success } from '$lib/toasts';
|
||||
import { IconRotateClockwise } from '$lib/components/icons';
|
||||
|
||||
export let data: PageData;
|
||||
const { statuses, diffs } = data;
|
||||
const { statuses, diffs, user, api, projectId } = data;
|
||||
|
||||
let summary = '';
|
||||
let description = '';
|
||||
|
||||
let selectedFiles = $statuses.map(({ path }) => path);
|
||||
const selectedDiffPath = writable($statuses.at(0)?.path);
|
||||
@ -14,14 +20,67 @@
|
||||
([diffs, selectedDiffPath]) => diffs[selectedDiffPath]
|
||||
);
|
||||
|
||||
const onCommit = (e: SubmitEvent) => {
|
||||
const reset = () => {
|
||||
summary = '';
|
||||
description = '';
|
||||
};
|
||||
|
||||
let isCommitting = false;
|
||||
let isGeneratingCommitMessage = false;
|
||||
|
||||
const onCommit = async (e: SubmitEvent) => {
|
||||
const form = e.target as HTMLFormElement;
|
||||
const formData = new FormData(form);
|
||||
const summary = formData.get('summary') as string;
|
||||
const description = formData.get('description') as string;
|
||||
const paths = formData.getAll('path') as string[];
|
||||
|
||||
// TODO
|
||||
isCommitting = true;
|
||||
commit({
|
||||
projectId,
|
||||
message: description.length > 0 ? `${summary}\n\n${description}` : summary,
|
||||
files: paths,
|
||||
push: false
|
||||
})
|
||||
.then(() => {
|
||||
success('Commit successfull!');
|
||||
reset();
|
||||
})
|
||||
.catch(() => {
|
||||
error('Failed to commit');
|
||||
})
|
||||
.finally(() => {
|
||||
isCommitting = false;
|
||||
});
|
||||
};
|
||||
|
||||
const onGenerateCommitMessage = async () => {
|
||||
if ($user === undefined) return;
|
||||
|
||||
const partialDiff = Object.fromEntries(
|
||||
Object.entries($diffs).filter(([key]) => selectedFiles.includes(key))
|
||||
);
|
||||
const diff = Object.values(partialDiff).join('\n').slice(0, 5000);
|
||||
|
||||
isGeneratingCommitMessage = true;
|
||||
api.summarize
|
||||
.commit($user.access_token, {
|
||||
diff,
|
||||
uid: projectId
|
||||
})
|
||||
.then((message) => {
|
||||
if (message === undefined) return;
|
||||
|
||||
const firstNewLine = message.indexOf('\n');
|
||||
summary = firstNewLine > -1 ? message.slice(0, firstNewLine) : message;
|
||||
description = firstNewLine > -1 ? message.slice(firstNewLine + 1) : '';
|
||||
})
|
||||
.catch(() => {
|
||||
error('Failed to generate commit message');
|
||||
})
|
||||
.finally(() => {
|
||||
isGeneratingCommitMessage = false;
|
||||
});
|
||||
};
|
||||
|
||||
const onGroupCheckboxClick = (e: Event) => {
|
||||
@ -33,8 +92,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
let summary = '';
|
||||
|
||||
$: isEnabled = summary.length > 0 && selectedFiles.length > 0;
|
||||
</script>
|
||||
|
||||
@ -47,10 +104,11 @@
|
||||
<header class="flex w-full items-center py-2 px-4">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="cursor-pointer"
|
||||
class="cursor-pointer disabled:opacity-50"
|
||||
on:click={onGroupCheckboxClick}
|
||||
checked={$statuses.length === selectedFiles.length}
|
||||
indeterminate={$statuses.length > selectedFiles.length && selectedFiles.length > 0}
|
||||
disabled={isCommitting || isGeneratingCommitMessage}
|
||||
/>
|
||||
<h1 class="m-auto flex">
|
||||
<span class="w-full text-center">{$statuses.length} changed files</span>
|
||||
@ -65,7 +123,8 @@
|
||||
class="flex items-center gap-2 border-gb-700 bg-gb-900"
|
||||
>
|
||||
<input
|
||||
class="ml-4 cursor-pointer py-2"
|
||||
class="ml-4 cursor-pointer py-2 disabled:opacity-50"
|
||||
disabled={isCommitting || isGeneratingCommitMessage}
|
||||
name="path"
|
||||
type="checkbox"
|
||||
bind:group={selectedFiles}
|
||||
@ -73,9 +132,10 @@
|
||||
/>
|
||||
<label class="flex w-full" for="path">
|
||||
<button
|
||||
disabled={isCommitting || isGeneratingCommitMessage}
|
||||
on:click|preventDefault={() => ($selectedDiffPath = path)}
|
||||
type="button"
|
||||
class="h-full w-full py-2 pr-4 text-left font-mono "
|
||||
class="h-full w-full py-2 pr-4 text-left font-mono disabled:opacity-50"
|
||||
use:collapsable={{ value: path, separator: '/' }}
|
||||
/>
|
||||
</label>
|
||||
@ -85,7 +145,8 @@
|
||||
|
||||
<input
|
||||
name="summary"
|
||||
class="rounded border border-gb-900 bg-gb-800 p-3"
|
||||
class="rounded border border-gb-900 bg-gb-800 p-3 disabled:opacity-50"
|
||||
disabled={isGeneratingCommitMessage || isCommitting}
|
||||
type="text"
|
||||
placeholder="Summary (required)"
|
||||
bind:value={summary}
|
||||
@ -94,25 +155,48 @@
|
||||
|
||||
<textarea
|
||||
name="description"
|
||||
class="rounded border border-gb-900 bg-gb-800 p-3"
|
||||
disabled={isGeneratingCommitMessage || isCommitting}
|
||||
class="rounded border border-gb-900 bg-gb-800 p-3 disabled:opacity-50"
|
||||
rows="10"
|
||||
placeholder="Description (optional)"
|
||||
bind:value={description}
|
||||
/>
|
||||
|
||||
<div class="flex justify-between">
|
||||
<input
|
||||
disabled={!isEnabled}
|
||||
type="submit"
|
||||
value="Commit changes"
|
||||
class="rounded bg-[#2563EB] py-2 px-4 text-lg disabled:cursor-not-allowed disabled:opacity-50"
|
||||
/>
|
||||
{#if isCommitting}
|
||||
<div
|
||||
class="flex gap-1 rounded bg-[#2563EB] py-2 px-4 text-lg disabled:cursor-not-allowed disabled:opacity-50"
|
||||
>
|
||||
<IconRotateClockwise class="h-5 w-5 animate-spin" />
|
||||
<span>Comitting...</span>
|
||||
</div>
|
||||
{:else}
|
||||
<button
|
||||
disabled={!isEnabled || isGeneratingCommitMessage}
|
||||
type="submit"
|
||||
class="rounded bg-[#2563EB] py-2 px-4 text-lg disabled:cursor-not-allowed disabled:opacity-50"
|
||||
>
|
||||
Commit changes
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="rounded bg-gradient-to-b from-[#623871] to-[#502E5C] py-2 px-4 text-lg"
|
||||
>
|
||||
✨ Generate commit message
|
||||
</button>
|
||||
{#if isGeneratingCommitMessage}
|
||||
<div
|
||||
class="flex items-center gap-1 rounded bg-gradient-to-b from-[#623871] to-[#502E5C] py-2 px-4 text-lg disabled:cursor-not-allowed disabled:opacity-50"
|
||||
>
|
||||
<IconRotateClockwise class="h-5 w-5 animate-spin" />
|
||||
<span>Generating commit message...</span>
|
||||
</div>
|
||||
{:else}
|
||||
<button
|
||||
type="button"
|
||||
disabled={$user === undefined}
|
||||
class="rounded bg-gradient-to-b from-[#623871] to-[#502E5C] py-2 px-4 text-lg disabled:cursor-not-allowed disabled:opacity-50"
|
||||
on:click|preventDefault={onGenerateCommitMessage}
|
||||
>
|
||||
✨ Generate commit message
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user