Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion standalone/src-tauri/capabilities/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,16 @@
"permissions": [
"core:default",
"opener:default",
{
"identifier": "opener:allow-open-path",
"allow": [
{
"path": "$APPLOCALDATA"
}
]
},
"shell:default",
"log:default",
"fs:default"
]
}
}
2 changes: 1 addition & 1 deletion standalone/src-tauri/capabilities/desktop.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
"cli:default",
"fs:default"
]
}
}
3 changes: 3 additions & 0 deletions standalone/src-tauri/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ fn resolve_extension_path(app_handle: &AppHandle) -> Option<PathBuf> {
}
}

// FIXME: in MacOS bundle, we should reference the library from Frameworks folder
// instead of Resources. However, either way require code signing setup, which is not
// yet done.
match app_handle.path().resource_dir() {
Ok(resource_dir) => {
let resource_path = resource_dir.join("resources").join(&lib_name);
Expand Down
2 changes: 1 addition & 1 deletion standalone/src/lib/components/JsonBlock.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
};
</script>

<div class="rounded-md border border-black/10">
<div class="rounded-md border border-black/10 overflow-hidden">
<div class="flex items-center justify-between border-b border-black/10 bg-slate-50 px-3 py-2 text-xs text-slate-500">
<span>{title}</span>
<Button type="button" class="hover:text-slate-700" onclick={handleCopy}>
Expand Down
77 changes: 51 additions & 26 deletions standalone/src/routes/settings/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
type WorkerStatus,
} from "$lib/providers/absurdData";
import { invoke } from "@tauri-apps/api/core";
import { revealItemInDir } from "@tauri-apps/plugin-opener";

const provider = getAbsurdProvider();
const defaults: SettingsInfo = {
Expand Down Expand Up @@ -54,6 +55,7 @@
const canCopyPath = $derived(
data.dbPath !== "--" && data.dbPath.trim().length > 0,
);
const canOpenFolder = $derived(canCopyPath && isTauriRuntime());
let copyStatus = $state<"idle" | "copied" | "error">("idle");
const showDevApi = $derived(isTauriRuntime());
const normalizedWorkerPath = $derived(workerPathDraft.trim());
Expand Down Expand Up @@ -174,6 +176,27 @@
}, 2000);
};

const resolveFolderPath = (path: string) => {
if (!path || path === "--") return "";
const normalized = path.replace(/\\/g, "/");
const lastSlash = normalized.lastIndexOf("/");
if (lastSlash <= 0) return path;
const dir = normalized.slice(0, lastSlash);
return path.includes("\\") ? dir.replaceAll("/", "\\") : dir;
};

const handleOpenFolder = async () => {
if (!canOpenFolder) {
return;
}

try {
await revealItemInDir(data.dbPath);
} catch (error) {
console.error("Failed to open database folder", error);
}
};

const syncWorkerStatus = (status: WorkerStatus) => {
workerStatus = status;
if (!workerPathTouched) {
Expand Down Expand Up @@ -375,33 +398,35 @@

<article class="rounded-lg border border-black/10 bg-white p-6">
<h2 class="text-lg font-semibold text-slate-900">Database</h2>
<p class="mt-1 text-sm text-slate-500">Primary storage location for task data.</p>
<p class="mt-1 text-sm text-slate-500">SQLite database information.</p>
<dl class="mt-4 space-y-3 text-sm">
<div class="space-y-2">
<div class="flex flex-wrap items-center justify-between gap-3">
<dt class="text-slate-500">File path</dt>
<div class="flex items-center gap-2">
<span
class="rounded-full border border-slate-200 bg-slate-50 px-2.5 py-1 text-[11px] font-semibold uppercase tracking-wide text-slate-600"
>
{dbSizeLabel}
</span>
<Button
type="button"
class="rounded-md border border-black/10 bg-white px-3 py-1 text-xs font-medium text-slate-700 disabled:cursor-not-allowed disabled:opacity-60"
disabled={!canCopyPath}
onclick={handleCopyPath}
>
{copyStatus === "copied"
? "Copied"
: copyStatus === "error"
? "Copy failed"
: "Copy"}
</Button>
</div>
</div>
<dd class="break-all rounded-md border border-black/10 bg-slate-50 px-3 py-2 font-mono text-xs text-slate-700">
{data.dbPath}
<div class="flex flex-wrap items-center justify-between gap-3">
<dt class="text-slate-500">Disk size</dt>
<dd class="font-medium text-slate-700">{dbSizeLabel}</dd>
</div>
<div class="flex flex-wrap items-center justify-between gap-3">
<dt class="text-slate-500">Actions</dt>
<dd class="flex flex-wrap items-center gap-2">
<Button
type="button"
class="rounded-md border border-black/10 bg-white px-3 py-1 text-xs font-medium text-slate-700 disabled:cursor-not-allowed disabled:opacity-60"
disabled={!canCopyPath}
onclick={handleCopyPath}
>
{copyStatus === "copied"
? "Copied"
: copyStatus === "error"
? "Copy failed"
: "Copy full path"}
</Button>
<Button
type="button"
class="rounded-md border border-black/10 bg-white px-3 py-1 text-xs font-medium text-slate-700 disabled:cursor-not-allowed disabled:opacity-60"
disabled={!canOpenFolder}
onclick={handleOpenFolder}
>
Open folder
</Button>
</dd>
</div>
</dl>
Expand Down
68 changes: 56 additions & 12 deletions standalone/src/routes/tasks/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
let taskRuns = $state<TaskRun[]>([]);
let totalCount = $state(0);
let expandedId = $state<string | null>(null);
let hoveredTaskId = $state<string | null>(null);
let isReady = $state(false);
let isLoading = $state(false);
let limit = $state(defaultLimit);
Expand All @@ -51,6 +52,19 @@
const toggleExpanded = (runId: string) => {
expandedId = expandedId === runId ? null : runId;
};
const applyTaskNameFilter = (name: string) => {
selectedTaskName = name;
if (activeSearch || searchTerm) {
activeSearch = "";
searchTerm = "";
updateQuery({ q: null });
}
};
const applyTaskIdFilter = (taskId: string) => {
searchTerm = taskId;
activeSearch = taskId;
updateQuery({ q: taskId });
};
const handleSearchInput = (event: Event) => {
const target = event.currentTarget as HTMLInputElement | null;
if (!target) return;
Expand Down Expand Up @@ -251,7 +265,7 @@
{#if totalCount === 0}
Showing 0 tasks
{:else}
Showing 1–{taskRuns.length} of {totalCount} tasks
Showing 1–{taskRuns.length} of {totalCount} task runs
{/if}
</span>
{#if isLoading}
Expand All @@ -269,12 +283,11 @@
<table class="min-w-full border-collapse text-left text-sm">
<thead class="bg-slate-100 text-xs font-semibold uppercase tracking-wide text-slate-600">
<tr>
<th class="px-4 py-3">Task ID</th>
<th class="px-4 py-3">Task Run</th>
<th class="px-4 py-3">Task Name</th>
<th class="px-4 py-3">Queue</th>
<th class="px-4 py-3">Status</th>
<th class="px-4 py-3">Attempt</th>
<th class="px-4 py-3">Run ID</th>
<th class="px-4 py-3">Age</th>
<th class="px-4 py-3"></th>
</tr>
Expand All @@ -285,7 +298,28 @@
class="border-t border-black/5 hover:bg-slate-50 hover:cursor-pointer"
onclick={() => toggleExpanded(run.runId)}
>
<td class="px-4 py-3 font-mono text-xs text-slate-600">{run.id}</td>
<td class="px-4 py-3">
<div class="flex flex-col gap-1">
<span class="font-mono text-xs text-slate-700">run: {run.runId}</span>
<button
type="button"
aria-label="Highlight task id"
class={`w-fit cursor-default text-left font-mono text-[10px] ${
hoveredTaskId === run.id
? "rounded bg-amber-50 px-1 text-amber-700"
: "text-slate-500"
}`}
onmouseenter={() => {
hoveredTaskId = run.id;
}}
onmouseleave={() => {
hoveredTaskId = null;
}}
>
task: {run.id}
</button>
</div>
</td>
<td class="px-4 py-3 text-slate-800">{run.name}</td>
<td class="px-4 py-3 text-slate-600">{run.queue}</td>
<td class="px-4 py-3">
Expand All @@ -296,13 +330,12 @@
</span>
</td>
<td class="px-4 py-3 text-slate-600">{run.attempt}</td>
<td class="px-4 py-3 font-mono text-xs text-slate-600">{run.runId}</td>
<td class="px-4 py-3 text-slate-600">{run.age}</td>
<td class="px-4 py-3 text-slate-600">{expandedId === run.runId ? "▲" : "▼"}</td>
</tr>
{#if expandedId === run.runId}
<tr class="border-t border-black/10 bg-white">
<td colspan="8" class="px-4 py-4">
<td colspan="7" class="px-4 py-4">
<div class="mt-4">
<div class="flex items-center justify-between">
<h3 class="text-sm font-semibold text-slate-800">Basic Information</h3>
Expand All @@ -329,9 +362,13 @@
<div class="flex gap-2">
<dt class="text-slate-500">Task Name:</dt>
<dd>
<a href={`/tasks/${run.id}`} class="text-slate-700 hover:underline">
<button
type="button"
class="cursor-pointer text-left text-slate-700 hover:underline"
onclick={() => applyTaskNameFilter(run.name)}
>
{run.name}
</a>
</button>
</dd>
</div>
<div class="flex gap-2">
Expand All @@ -341,12 +378,19 @@
<div class="flex gap-2">
<dt class="text-slate-500">Task ID:</dt>
<dd>
<a
href={`/tasks/${run.id}`}
class="rounded bg-blue-50 px-1 py-0.5 font-mono text-xs text-blue-700 hover:underline"
<button
type="button"
class="cursor-pointer rounded bg-blue-50 px-1 py-0.5 text-left font-mono text-xs text-blue-700 hover:underline"
onclick={() => applyTaskIdFilter(run.id)}
onmouseenter={() => {
hoveredTaskId = run.id;
}}
onmouseleave={() => {
hoveredTaskId = null;
}}
>
{run.id}
</a>
</button>
</dd>
</div>
<div class="flex gap-2">
Expand Down