Skip to content

Commit

Permalink
Redirect to search after successful upload
Browse files Browse the repository at this point in the history
  • Loading branch information
eyeseast committed Apr 16, 2024
1 parent ebf3628 commit 5c0265a
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 20 deletions.
15 changes: 14 additions & 1 deletion src/lib/api/accounts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { vi, test, describe, it, expect, beforeEach, afterEach } from "vitest";
import { BASE_API_URL } from "@/config/config";
import * as fixtures from "@/test/fixtures/accounts";

import { getMe, getOrg } from "./accounts";
import { getMe, getOrg, userDocs } from "./accounts";
import { slugify } from "@/util/string.js";

describe("getMe", async () => {
let mockFetch;
Expand Down Expand Up @@ -62,3 +63,15 @@ test("getOrg", async () => {

test.todo("users.get");
test.todo("users.list");

describe("utility methods", () => {
test("userDocs", () => {
expect(userDocs(fixtures.me, "public")).toStrictEqual(
`+user:${slugify(fixtures.me.name)}-${fixtures.me.id} access:public`,
);

expect(userDocs(fixtures.me, "private")).toStrictEqual(
`+user:${slugify(fixtures.me.name)}-${fixtures.me.id} access:private`,
);
});
});
13 changes: 13 additions & 0 deletions src/lib/api/accounts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { Maybe, User, Org } from "@/api/types";
import type { Access } from "./types";
import { BASE_API_URL } from "@/config/config.js";
import { slugify } from "@/util/string.js";

type Fetch = typeof globalThis.fetch;

Expand All @@ -21,3 +23,14 @@ export async function getOrg(fetch: Fetch, id: number): Promise<Org> {
const resp = await fetch(endpoint, { credentials: "include" });
return resp.json();
}

// link helpers

/**
* Generate search params for a user's documents
* @param user
* @param access
*/
export function userDocs(user: User, access: Access): string {
return `+user:${slugify(user.name)}-${user.id} access:${access}`;
}
9 changes: 9 additions & 0 deletions src/lib/api/fixtures/documents/pending.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[
{
"doc_id": 20000033,
"images": 2,
"texts": 2,
"text_positions": 5,
"pages": 11
}
]
8 changes: 8 additions & 0 deletions src/lib/api/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,12 @@ export interface OCREngine {
help?: string;
}

export interface Pending {
doc_id: number;
images: number;
texts: number;
text_positions: number;
pages: number;
}

export type ProjectMembershipList = Page<ProjectMembershipItem>;
44 changes: 31 additions & 13 deletions src/lib/components/forms/DocumentUpload.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script context="module" lang="ts">
import type { ActionResult } from "@sveltejs/kit";
import { DEFAULT_LANGUAGE } from "@/config/config.js";
import { userDocs } from "$lib/api/accounts";
/**
* Collect form data into documents and do three-step upload.
Expand All @@ -9,6 +10,7 @@
export async function upload(
form: FormData,
csrf_token: string,
user: User,
fetch = globalThis.fetch,
): Promise<ActionResult> {
// one per file
Expand All @@ -35,7 +37,7 @@
language,
projects: projects.map((p: Project) => p.id),
revision_control,
original_extension: ext[ext.length - 1],
original_extension: ext,
};
});
Expand Down Expand Up @@ -73,36 +75,37 @@
// todo: i18n
if (process_response.ok) {
const query = new URLSearchParams([["q", userDocs(user, access)]]);
return {
type: "success",
status: 201,
data: {
success: true,
message: `Uploaded ${created.length} documents`,
},
type: "redirect",
status: 302,
location: "/app/?" + query.toString(),
};
}
return {
type: "error",
status: process_response.status,
error: await process_response.text(),
error: await process_response.json(),
};
}
</script>

<script lang="ts">
import type { Writable } from "svelte/store";
import type {
Access,
Document,
DocumentUpload,
OCREngine,
Project,
} from "$lib/api/types";
import type { User } from "@/api/types/orgAndUser";
import { applyAction } from "$app/forms";
import { goto } from "$app/navigation";
import { filesize } from "filesize";
import { afterUpdate } from "svelte";
import { afterUpdate, getContext } from "svelte";
import { _ } from "svelte-i18n";
import {
Alert16,
Expand Down Expand Up @@ -141,6 +144,8 @@
export let files: File[] = [];
export let projects: Project[] = [];
const me: Writable<User> = getContext("me");
let loading = false;
let uploader: HTMLInputElement;
Expand Down Expand Up @@ -181,7 +186,7 @@
const form = e.target as HTMLFormElement;
const fd = new FormData(form);
const result = await upload(fd, csrf_token);
const result = await upload(fd, csrf_token, $me);
// send data up
await applyAction(result);
Expand All @@ -191,6 +196,10 @@
files = [];
}
if (result.type === "redirect") {
goto(result.location, { invalidateAll: true });
}
loading = false;
}
Expand Down Expand Up @@ -236,7 +245,12 @@
{/if}
</p>
<div class="title">
<Text name="title" value={filenameToTitle(file.name)} required />
<Text
name="title"
value={filenameToTitle(file.name)}
required
disabled={loading}
/>
<input type="hidden" name="filename" value={file.name} />
</div>
<button
Expand Down Expand Up @@ -267,11 +281,15 @@
onDrop={addFiles}
disabled={loading}
>
<div class="fileDrop" class:active={fileDropActive}>
<div
class="fileDrop"
class:active={fileDropActive}
class:disabled={loading}
>
<p class="drop-instructions">Drag and drop files here</p>
<Flex align="center" justify="center">
<span class="drop-instructions-or">or</span>
<FileInput multiple onFileSelect={addFiles}
<FileInput multiple onFileSelect={addFiles} disabled={loading}
><File16 /> Select Files</FileInput
>
</Flex>
Expand Down
6 changes: 4 additions & 2 deletions src/lib/components/inputs/File.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
export let multiple = false;
export let buttonMode: ComponentProps<Button>["mode"] = "ghost";
export let files: FileList = null;
export let disabled = false;
// Bound to the file picker input
let picker: HTMLInputElement;
Expand All @@ -32,15 +33,16 @@
}
</script>

<span class="container">
<Button mode={buttonMode} on:click={openFilePicker}>
<span class="container" class:disabled>
<Button mode={buttonMode} on:click={openFilePicker} {disabled}>
<slot />
</Button>
<input
type="file"
{name}
accept={DOCUMENT_TYPES.join(",")}
{multiple}
{disabled}
bind:files
bind:this={picker}
on:change={handleFiles}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/components/inputs/Text.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
export let placeholder = "";
export let value = "";
export let required = false;
export let disabled = false;
</script>

<input
type="text"
{name}
{placeholder}
{required}
{disabled}
bind:value
on:change
on:input
Expand Down
7 changes: 3 additions & 4 deletions src/routes/app/sidebar/Documents.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,15 @@
import { APP_URL } from "@/config/config";
import { slugify } from "@/util/string.js";
import { userDocs } from "$lib/api/accounts";
const me: Writable<User> = getContext("me");
const org: Writable<Org> = getContext("org");
$: query = $page.url.searchParams.get("q") || "";
// +user:chris-amico-1020 +access:public
$: mine = $me ? `+user:${slugify($me.name)}-${$me.id}` : "";
$: minePublic = `${mine} +access:public`;
$: minePrivate = `${mine} +access:private`;
$: minePublic = userDocs($me, "public");
$: minePrivate = userDocs($me, "private");
// +organization:muckrock-125
$: orgDocs = $org ? `+organization:${slugify($org.name)}-${$org.id}` : "";
Expand Down

0 comments on commit 5c0265a

Please sign in to comment.