[ui] move most of search logic out of component
parent
d4f88933b8
commit
642590cce9
|
@ -0,0 +1,40 @@
|
||||||
|
import type { UpEntry } from "upend";
|
||||||
|
import type { ListingResult } from "upend/types";
|
||||||
|
import { fetchEntry, query as queryFn } from "../lib/entity";
|
||||||
|
|
||||||
|
export function baseSearch(query: string) {
|
||||||
|
return queryFn(() => `(matches ? ? (contains "${query}"))`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getObjects(entries: UpEntry[]): Promise<string[]> {
|
||||||
|
const labelled = entries
|
||||||
|
.filter((e) => e.attribute == "LBL")
|
||||||
|
.map((e) => e.entity);
|
||||||
|
const aliased = entries
|
||||||
|
.filter((e) => e.attribute === "ALIAS")
|
||||||
|
.map(async (e) => {
|
||||||
|
const entry = await fetchEntry(e.entity);
|
||||||
|
return String(entry.value.c);
|
||||||
|
});
|
||||||
|
return labelled.concat(await Promise.all(aliased));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createLabelled(label: string) {
|
||||||
|
const response = await fetch(`/api/obj`, {
|
||||||
|
method: "PUT",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({
|
||||||
|
attribute: "LBL",
|
||||||
|
value: {
|
||||||
|
t: "Value",
|
||||||
|
c: label,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Failed to create object: ${await response.text()}`);
|
||||||
|
}
|
||||||
|
const result = (await response.json()) as ListingResult;
|
||||||
|
const address = Object.values(result)[0].entity;
|
||||||
|
return address;
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { fetchEntry, query as queryFn } from "../lib/entity";
|
|
||||||
import debounce from "lodash/debounce";
|
import debounce from "lodash/debounce";
|
||||||
import { Readable, readable } from "svelte/store";
|
import { Readable, readable } from "svelte/store";
|
||||||
import type { UpEntry, UpListing, UpObject } from "upend";
|
import type { UpEntry, UpListing, UpObject } from "upend";
|
||||||
|
@ -8,7 +7,7 @@
|
||||||
import UpObjectDisplay from "../components/display/UpObject.svelte";
|
import UpObjectDisplay from "../components/display/UpObject.svelte";
|
||||||
import UpObjectCard from "../components/display/UpObjectCard.svelte";
|
import UpObjectCard from "../components/display/UpObjectCard.svelte";
|
||||||
import { useNavigate } from "svelte-navigator";
|
import { useNavigate } from "svelte-navigator";
|
||||||
import type { ListingResult } from "upend/types";
|
import { baseSearch, createLabelled, getObjects } from "../util/search";
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
export let query: string;
|
export let query: string;
|
||||||
|
@ -22,35 +21,14 @@
|
||||||
let result: Readable<UpListing> = readable();
|
let result: Readable<UpListing> = readable();
|
||||||
let error: Readable<unknown> = readable();
|
let error: Readable<unknown> = readable();
|
||||||
$: if (debouncedQuery.length) {
|
$: if (debouncedQuery.length) {
|
||||||
({ result, error } = queryFn(
|
({ result, error } = baseSearch(debouncedQuery));
|
||||||
() => `(matches ? ? (contains "${debouncedQuery}"))`
|
exactHits = [];
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
$: entries = ($result?.entries || []).sort((a, b) =>
|
|
||||||
a.address.localeCompare(b.address)
|
|
||||||
);
|
|
||||||
|
|
||||||
async function getObjects(entries: UpEntry[]): Promise<string[]> {
|
|
||||||
exactHits.length = 0;
|
|
||||||
const labelled = entries
|
|
||||||
.filter((e) => e.attribute == "LBL")
|
|
||||||
.map((e) => e.entity);
|
|
||||||
const aliased = entries
|
|
||||||
.filter((e) => e.attribute === "ALIAS")
|
|
||||||
.map(async (e) => {
|
|
||||||
const entry = await fetchEntry(e.entity);
|
|
||||||
return String(entry.value.c);
|
|
||||||
});
|
|
||||||
return labelled.concat(await Promise.all(aliased));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$: objects = getObjects($result?.entries || []);
|
$: objects = getObjects($result?.entries || []);
|
||||||
|
|
||||||
let exactHits = [];
|
let exactHits = [];
|
||||||
|
|
||||||
function onResolved(address: string, ids: string[]) {
|
function onResolved(address: string, ids: string[]) {
|
||||||
console.log({ address, ids });
|
|
||||||
|
|
||||||
if (ids.some((id) => id.toLowerCase() === query.toLowerCase())) {
|
if (ids.some((id) => id.toLowerCase() === query.toLowerCase())) {
|
||||||
if (!exactHits.includes(address)) {
|
if (!exactHits.includes(address)) {
|
||||||
exactHits.push(address);
|
exactHits.push(address);
|
||||||
|
@ -60,23 +38,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
async function create() {
|
async function create() {
|
||||||
const response = await fetch(`/api/obj`, {
|
const createdAddress = await createLabelled(query);
|
||||||
method: "PUT",
|
navigate(`/browse/${createdAddress}`);
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({
|
|
||||||
attribute: "LBL",
|
|
||||||
value: {
|
|
||||||
t: "Value",
|
|
||||||
c: query,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Failed to create object: ${await response.text()}`);
|
|
||||||
}
|
|
||||||
const result = (await response.json()) as ListingResult;
|
|
||||||
const address = Object.values(result)[0].entity;
|
|
||||||
navigate(`/browse/${address}`);
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -122,10 +85,10 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="raw">
|
<section class="raw">
|
||||||
{#if entries.length}
|
{#if $result?.entries.length}
|
||||||
<h2>Raw results</h2>
|
<h2>Raw results</h2>
|
||||||
<ul>
|
<ul>
|
||||||
{#each entries as entry}
|
{#each $result.entries as entry}
|
||||||
<li><UpEntryDisplay {entry} /></li>
|
<li><UpEntryDisplay {entry} /></li>
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
Loading…
Reference in New Issue