feat: implement description
This commit is contained in:
40
api/Cargo.lock
generated
40
api/Cargo.lock
generated
@@ -29,7 +29,7 @@ dependencies = [
|
|||||||
"actix-rt",
|
"actix-rt",
|
||||||
"actix-service",
|
"actix-service",
|
||||||
"actix-utils",
|
"actix-utils",
|
||||||
"base64",
|
"base64 0.22.1",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"brotli",
|
"brotli",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -252,6 +252,7 @@ dependencies = [
|
|||||||
"reqwest 0.13.1",
|
"reqwest 0.13.1",
|
||||||
"sentry",
|
"sentry",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_dynamo",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"thiserror 2.0.17",
|
"thiserror 2.0.17",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -685,6 +686,12 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
|
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.21.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.22.1"
|
version = "0.22.1"
|
||||||
@@ -1737,7 +1744,7 @@ version = "0.1.19"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f"
|
checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@@ -1969,7 +1976,7 @@ version = "10.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c76e1c7d7df3e34443b3621b459b066a7b79644f059fc8b2db7070c825fd417e"
|
checksum = "c76e1c7d7df3e34443b3621b459b066a7b79644f059fc8b2db7070c825fd417e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64 0.22.1",
|
||||||
"ed25519-dalek",
|
"ed25519-dalek",
|
||||||
"getrandom 0.2.17",
|
"getrandom 0.2.17",
|
||||||
"hmac",
|
"hmac",
|
||||||
@@ -2558,7 +2565,7 @@ version = "3.0.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
|
checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64 0.22.1",
|
||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2867,7 +2874,7 @@ version = "0.12.28"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
|
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@@ -2905,7 +2912,7 @@ version = "0.13.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04e9018c9d814e5f30cc16a0f03271aeab3571e609612d9fe78c1aa8d11c2f62"
|
checksum = "04e9018c9d814e5f30cc16a0f03271aeab3571e609612d9fe78c1aa8d11c2f62"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@@ -3368,6 +3375,17 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_dynamo"
|
||||||
|
version = "4.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "873a97c3f7a67dd042bceb47d056d288424b82d4c66b0a25e1a3b34675620951"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.21.7",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.149"
|
version = "1.0.149"
|
||||||
@@ -3541,7 +3559,7 @@ version = "0.8.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6"
|
checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
"crc",
|
"crc",
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
@@ -3615,7 +3633,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526"
|
checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
"base64",
|
"base64 0.22.1",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -3657,7 +3675,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46"
|
checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
"base64",
|
"base64 0.22.1",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"crc",
|
"crc",
|
||||||
@@ -4172,7 +4190,7 @@ version = "3.1.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d39cb1dbab692d82a977c0392ffac19e188bd9186a9f32806f0aaa859d75585a"
|
checksum = "d39cb1dbab692d82a977c0392ffac19e188bd9186a9f32806f0aaa859d75585a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64 0.22.1",
|
||||||
"der",
|
"der",
|
||||||
"log",
|
"log",
|
||||||
"native-tls",
|
"native-tls",
|
||||||
@@ -4189,7 +4207,7 @@ version = "0.5.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d81f9efa9df032be5934a46a068815a10a042b494b6a58cb0a1a97bb5467ed6f"
|
checksum = "d81f9efa9df032be5934a46a068815a10a042b494b6a58cb0a1a97bb5467ed6f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64 0.22.1",
|
||||||
"http 1.4.0",
|
"http 1.4.0",
|
||||||
"httparse",
|
"httparse",
|
||||||
"log",
|
"log",
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ mime_guess = "2.0.5"
|
|||||||
reqwest = { version = "0.13.1", features = ["json", "query"] }
|
reqwest = { version = "0.13.1", features = ["json", "query"] }
|
||||||
sentry = { version = "0.46.1", features = ["actix", "tracing"] }
|
sentry = { version = "0.46.1", features = ["actix", "tracing"] }
|
||||||
serde = "1.0.228"
|
serde = "1.0.228"
|
||||||
|
serde_dynamo = "4.3.0"
|
||||||
sqlx = { version = "0.8.6", features = ["postgres", "runtime-tokio", "tls-native-tls"] }
|
sqlx = { version = "0.8.6", features = ["postgres", "runtime-tokio", "tls-native-tls"] }
|
||||||
thiserror = "2.0.17"
|
thiserror = "2.0.17"
|
||||||
tokio = "1.49.0"
|
tokio = "1.49.0"
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ pub async fn get_repos(
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r| r.id)
|
.map(|r| r.id)
|
||||||
.collect::<HashSet<String>>();
|
.collect::<HashSet<String>>();
|
||||||
|
println!("{added_ids:?}");
|
||||||
let data = response
|
let data = response
|
||||||
.json::<Vec<Repository>>()
|
.json::<Vec<Repository>>()
|
||||||
.await?
|
.await?
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Button } from 'bits-ui';
|
import { AlertDialog, Button } from 'bits-ui';
|
||||||
import { GitBranch, Star, Clock, Import, Search, RefreshCw, LoaderCircle } from '@lucide/svelte';
|
import { GitBranch, Star, Clock, Import, Search, RefreshCw, LoaderCircle } from '@lucide/svelte';
|
||||||
import type { Repository } from './types/repo';
|
import type { Repository } from './types/repo';
|
||||||
import { createQuery } from '@tanstack/svelte-query';
|
import { createQuery } from '@tanstack/svelte-query';
|
||||||
@@ -59,12 +59,25 @@
|
|||||||
const repos = $derived(searching ? (searchResultsQuery.data ?? []) : (query.data ?? []));
|
const repos = $derived(searching ? (searchResultsQuery.data ?? []) : (query.data ?? []));
|
||||||
const isPending = $derived(searching ? searchResultsQuery.isPending : query.isPending);
|
const isPending = $derived(searching ? searchResultsQuery.isPending : query.isPending);
|
||||||
|
|
||||||
const handleImport = async (repo: Repository) => {
|
let dialogOpen = $state(false);
|
||||||
|
let selectedRepo = $state<Repository | null>(null);
|
||||||
|
let description = $state('');
|
||||||
|
|
||||||
|
const openDialog = (repo: Repository) => {
|
||||||
if (added.includes(repo.id)) {
|
if (added.includes(repo.id)) {
|
||||||
toast.warning('Repository already imported');
|
toast.warning('Repository already imported');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
adding = repo.id;
|
selectedRepo = repo;
|
||||||
|
description = repo.description ?? '';
|
||||||
|
dialogOpen = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleImport = async () => {
|
||||||
|
if (!selectedRepo) return;
|
||||||
|
adding = selectedRepo.id;
|
||||||
|
dialogOpen = false;
|
||||||
|
|
||||||
let response = await fetch('/api/v0/user/repo/add', {
|
let response = await fetch('/api/v0/user/repo/add', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -72,8 +85,9 @@
|
|||||||
Authorization: (await apiClient.getToken()) ?? ''
|
Authorization: (await apiClient.getToken()) ?? ''
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
id: repo.id.toString(),
|
id: selectedRepo.id.toString(),
|
||||||
full_name: repo.full_name
|
full_name: selectedRepo.full_name,
|
||||||
|
description
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
@@ -84,8 +98,10 @@
|
|||||||
} else {
|
} else {
|
||||||
toast.success('Successfully added repository');
|
toast.success('Successfully added repository');
|
||||||
}
|
}
|
||||||
added.push(repo.id);
|
added.push(selectedRepo.id);
|
||||||
adding = null;
|
adding = null;
|
||||||
|
selectedRepo = null;
|
||||||
|
description = '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const languageColors: Record<string, string> = {
|
const languageColors: Record<string, string> = {
|
||||||
@@ -161,7 +177,7 @@
|
|||||||
? 'border-success-border bg-success'
|
? 'border-success-border bg-success'
|
||||||
: 'bg-primary'} disabled:cursor-default disabled:opacity-50"
|
: 'bg-primary'} disabled:cursor-default disabled:opacity-50"
|
||||||
disabled={adding !== null}
|
disabled={adding !== null}
|
||||||
onclick={() => handleImport(repo)}
|
onclick={() => openDialog(repo)}
|
||||||
>
|
>
|
||||||
{#if adding === repo.id}
|
{#if adding === repo.id}
|
||||||
<RefreshCw class="h-4 w-4 animate-spin" />
|
<RefreshCw class="h-4 w-4 animate-spin" />
|
||||||
@@ -189,3 +205,52 @@
|
|||||||
You must have a dist/ folder with index.html + index.wasm
|
You must have a dist/ folder with index.html + index.wasm
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<AlertDialog.Root bind:open={dialogOpen}>
|
||||||
|
<AlertDialog.Portal>
|
||||||
|
<AlertDialog.Overlay class="fixed inset-0 z-50 bg-black/80" />
|
||||||
|
<AlertDialog.Content
|
||||||
|
class="fixed top-1/2 left-1/2 z-50 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 rounded-xl border border-border bg-surface p-6 shadow-xl"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<AlertDialog.Title class="text-lg font-semibold text-text-primary">
|
||||||
|
Add Repository
|
||||||
|
</AlertDialog.Title>
|
||||||
|
<AlertDialog.Description class="text-sm text-text-secondary">
|
||||||
|
{#if selectedRepo}
|
||||||
|
You are about to add <span class="font-semibold text-text-primary"
|
||||||
|
>{selectedRepo.full_name}</span
|
||||||
|
>. Please provide a description for your project.
|
||||||
|
{/if}
|
||||||
|
</AlertDialog.Description>
|
||||||
|
|
||||||
|
<div class="mt-2">
|
||||||
|
<label for="description" class="mb-2 block text-sm font-medium text-text-primary">
|
||||||
|
Description
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
id="description"
|
||||||
|
bind:value={description}
|
||||||
|
placeholder="Describe your project..."
|
||||||
|
rows="3"
|
||||||
|
class="w-full rounded-lg border border-border-hover bg-surface-hover px-3 py-2 text-text-primary placeholder-text-muted transition-colors outline-none focus:border-border-focus focus:ring-1 focus:ring-border-focus"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-6 flex justify-end gap-3">
|
||||||
|
<AlertDialog.Cancel
|
||||||
|
class="rounded-lg border border-border px-4 py-2 text-sm font-medium text-text-secondary transition-colors hover:bg-surface-hover hover:text-text-primary"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</AlertDialog.Cancel>
|
||||||
|
<AlertDialog.Action
|
||||||
|
class="rounded-lg bg-primary px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-primary/90"
|
||||||
|
onclick={handleImport}
|
||||||
|
>
|
||||||
|
Continue
|
||||||
|
</AlertDialog.Action>
|
||||||
|
</div>
|
||||||
|
</AlertDialog.Content>
|
||||||
|
</AlertDialog.Portal>
|
||||||
|
</AlertDialog.Root>
|
||||||
|
|||||||
@@ -151,6 +151,14 @@ button:focus-visible {
|
|||||||
transform-origin: top;
|
transform-origin: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-alert-dialog-content][data-state="open"] {
|
||||||
|
animation: grow-in 150ms ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-alert-dialog-content][data-state="closed"] {
|
||||||
|
animation: grow-out 150ms ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: light) {
|
@media (prefers-color-scheme: light) {
|
||||||
:root {
|
:root {
|
||||||
color: #213547;
|
color: #213547;
|
||||||
|
|||||||
Reference in New Issue
Block a user