Spaces:
Running
Running
<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> | |