Spaces:
Sleeping
Sleeping
| <script lang="ts"> | |
| import { onMount } from "svelte"; | |
| import SvelteTable, { type TableColumn } from "svelte-table"; | |
| import Row from "./Row"; | |
| import { fetchRows } from "./bridge"; | |
| import { statusMessage } from "./store"; | |
| import SearchButtonComponent from "./SearchButtonComponent.svelte"; | |
| let rows: Row[] = []; | |
| let columns: TableColumn<Row>[] = [ | |
| { | |
| key: "Name", | |
| title: "Name", | |
| value: (v: Row) => v.Name || v.Project || v.Code || v.Paper || "N/A", | |
| sortable: true, | |
| renderValue: (v: Row) => { | |
| let url; | |
| if (v.Project) { | |
| url = v.Project; | |
| } else if (v.Code) { | |
| url = v.Code; | |
| } else if (v.Paper) { | |
| url = v.Paper; | |
| } else if (v.Space) { | |
| url = v.Space; | |
| } else if (v.Model) { | |
| url = v.Model; | |
| } else if (v.Dataset) { | |
| url = v.Dataset; | |
| } | |
| let name = v.Name || url || ""; | |
| let renderName = name; | |
| if (name.length > 64) { | |
| renderName = name.slice(0, 60) + "..."; | |
| } | |
| return `<a href="${url}" target="_blank" title="${name}">${renderName}</a>`; | |
| }, | |
| searchValue: (v: Row) => { | |
| let searchValue = v.Name || ""; | |
| if (v.Project) { | |
| searchValue += " " + v.Project; | |
| } | |
| if (v.Code) { | |
| searchValue += " " + v.Code; | |
| } | |
| if (v.Paper) { | |
| searchValue += " " + v.Paper; | |
| } | |
| if (v.Space) { | |
| searchValue += " " + v.Space; | |
| } | |
| if (v.Model) { | |
| searchValue += " " + v.Model; | |
| } | |
| if (v.Dataset) { | |
| searchValue += " " + v.Dataset; | |
| } | |
| return searchValue; | |
| }, | |
| parseHTML: true, | |
| hideFilterHeader: true, | |
| }, | |
| { | |
| key: "Search", | |
| title: "", | |
| value: (v: Row) => "", | |
| sortable: false, | |
| renderComponent: SearchButtonComponent, | |
| hideFilterHeader: true, | |
| }, | |
| { | |
| key: "Date", | |
| title: "Date", | |
| value: (v: Row) => v.Date || "", | |
| sortable: true, | |
| searchValue: (v: Row) => v.Date || "", | |
| renderValue: (v: Row) => { | |
| if (!v.Date) return ""; | |
| let renderDate = v.Date; | |
| // Convert ISO to YYYY-MM-DD | |
| if (v.Date.includes("T")) { | |
| renderDate = v.Date.split("T")[0]; | |
| } | |
| return `<span title="${v.Date}">${renderDate}</span>`; | |
| }, | |
| parseHTML: true, | |
| }, | |
| { | |
| key: "Authors", | |
| title: "Authors", | |
| value: (v: Row) => v.Authors.join(", "), | |
| sortable: true, | |
| searchValue: (v: Row) => v.Authors.join(" "), | |
| renderValue: (v: Row) => { | |
| let authors = v.Authors.join(", "); | |
| let renderAuthors = v.Authors.join(", "); | |
| if (authors.length > 24) { | |
| renderAuthors = renderAuthors.slice(0, 20) + "..."; | |
| } | |
| return `<span title="${authors}">${renderAuthors}</span>`; | |
| }, | |
| parseHTML: true, | |
| }, | |
| { | |
| key: "Paper", | |
| title: "Paper", | |
| value: (v: Row) => v.Paper || "", | |
| sortable: true, | |
| searchValue: (v: Row) => v.Paper || "", | |
| renderValue: (v: Row) => { | |
| if (!v.Paper) return ""; | |
| const url = v.Paper; | |
| let name = v.Paper; | |
| if (url.includes("arxiv.org/")) { | |
| name = `arxiv/${url.split("arxiv.org/")[1]}`; | |
| } else if (url.includes("huggingface.co/papers/")) { | |
| name = `hf/${url.split("huggingface.co/papers/")[1]}`; | |
| } | |
| let displayName = name.replace(".pdf", ""); | |
| if (displayName.length > 24) { | |
| displayName = displayName.slice(0, 20) + "..."; | |
| } | |
| return `<a href="${url}" target="_blank" title="${name}">${displayName}</a>`; | |
| }, | |
| parseHTML: true, | |
| }, | |
| { | |
| key: "Code", | |
| title: "Code", | |
| value: (v: Row) => v.Code || "", | |
| sortable: true, | |
| searchValue: (v: Row) => v.Code || "", | |
| renderValue: (v: Row) => { | |
| let codeUrl; | |
| let codeDisplay; | |
| if (v.Code) { | |
| codeUrl = v.Code; | |
| if (v.Code.includes("github.com")) { | |
| codeDisplay = `gh/${v.Code.split("github.com/")[1].slice(0, 16)}`; | |
| } else { | |
| codeDisplay = v.Code.slice(0, 16) + "..."; | |
| } | |
| } | |
| if (!codeDisplay) { | |
| return ""; | |
| } | |
| if (codeUrl) { | |
| return `<a href="${codeUrl}" target="_blank" title="${codeUrl}">${codeDisplay}</a>`; | |
| } | |
| return codeDisplay; | |
| }, | |
| parseHTML: true, | |
| }, | |
| { | |
| key: "License", | |
| title: "License", | |
| value: (v: Row) => v.License || "", | |
| sortable: true, | |
| searchValue: (v: Row) => v.License || "", | |
| renderValue: (v: Row) => { | |
| if (!v.License) return ""; | |
| let displayLicense = v.License; | |
| if (v.License.length > 24) { | |
| displayLicense = v.License.slice(0, 20) + "..."; | |
| } | |
| return `<span title="${v.License}">${displayLicense}</span>`; | |
| }, | |
| parseHTML: true, | |
| }, | |
| { | |
| key: "Space", | |
| title: "Space", | |
| value: (v: Row) => v.Space || "", | |
| sortable: true, | |
| searchValue: (v: Row) => v.Space || "", | |
| renderValue: (v: Row) => { | |
| if (!v.Space) return ""; | |
| if (v.Space.includes("huggingface.co")) { | |
| return `<a href="${v.Space}" target="_blank">hf/${v.Space.split("huggingface.co/")[1].slice( | |
| 0, | |
| 16 | |
| )}</a>`; | |
| } | |
| return `<a href="${v.Space}" target="_blank" title="${v.Space}">${v.Space.slice(0, 16)}...</a>`; | |
| }, | |
| parseHTML: true, | |
| }, | |
| { | |
| key: "Model", | |
| title: "Model", | |
| value: (v: Row) => v.Model || "", | |
| sortable: true, | |
| searchValue: (v: Row) => v.Model || "", | |
| renderValue: (v: Row) => { | |
| if (!v.Model) return ""; | |
| if (v.Model.includes("huggingface.co")) { | |
| return `<a href="${v.Model}" target="_blank">hf/${v.Model.split("huggingface.co/")[1].slice( | |
| 0, | |
| 16 | |
| )}</a>`; | |
| } | |
| return `<a href="${v.Model}" target="_blank" title="${v.Model}">${v.Model.slice(0, 16)}...</a>`; | |
| }, | |
| parseHTML: true, | |
| }, | |
| { | |
| key: "Dataset", | |
| title: "Dataset", | |
| value: (v: Row) => v.Dataset || "", | |
| sortable: true, | |
| searchValue: (v: Row) => v.Dataset || "", | |
| renderValue: (v: Row) => { | |
| if (!v.Dataset) return ""; | |
| if (v.Dataset.includes("huggingface.co")) { | |
| return `<a href="${v.Dataset}" target="_blank">hf/${v.Dataset.split("huggingface.co/")[1].slice( | |
| 0, | |
| 16 | |
| )}</a>`; | |
| } else if (v.Dataset.includes("drive.google.com")) { | |
| return `<a href="${v.Dataset}" target="_blank">drive/${v.Dataset.split( | |
| "drive.google.com/" | |
| )[1].slice(0, 16)}</a>`; | |
| } else if (v.Dataset.includes("github.com")) { | |
| return `<a href="${v.Dataset}" target="_blank">gh/${v.Dataset.split("github.com/")[1].slice( | |
| 0, | |
| 16 | |
| )}</a>`; | |
| } | |
| return `<a href="${v.Dataset}" target="_blank" title="${v.Dataset}">${v.Dataset.slice(0, 16)}...</a>`; | |
| }, | |
| parseHTML: true, | |
| }, | |
| ]; | |
| let selection: Record<string | number, any> = {}; | |
| let overrideSelection = false; | |
| let searchValue = ""; | |
| let sortBy: string = "Date"; | |
| let sortOrder: 1 | -1 | 0 = -1; | |
| $: { | |
| if (searchValue !== "") { | |
| selection = { Name: searchValue }; | |
| overrideSelection = true; | |
| } else { | |
| if (overrideSelection) { | |
| selection = {}; | |
| overrideSelection = false; | |
| } | |
| } | |
| } | |
| async function refreshRows() { | |
| fetching = true; | |
| try { | |
| const fetchedRows = await fetchRows(); | |
| rows = fetchedRows || []; | |
| } catch (error) { | |
| console.error(error); | |
| } finally { | |
| fetching = false; | |
| } | |
| } | |
| onMount(() => { | |
| refreshRows(); | |
| }); | |
| let fetching = false; | |
| </script> | |
| {#if fetching} | |
| <div style="text-align: center; margin-top: 1rem;"> | |
| <p>{@html $statusMessage}</p> | |
| </div> | |
| {:else} | |
| <!--spacer--> | |
| <div style="height: 1rem;" /> | |
| <SvelteTable {columns} {rows} bind:sortBy bind:sortOrder bind:filterSelections={selection} /> | |
| {/if} | |
| <style> | |
| :global(td) { | |
| border-top: 1px solid #e0e0e0; | |
| } | |
| </style> | |