feat(webui): Surface view as Column in Browse
ci/woodpecker/push/woodpecker Pipeline failed
Details
ci/woodpecker/push/woodpecker Pipeline failed
Details
parent
044e19e9a7
commit
27aeca9f4f
|
@ -9,7 +9,6 @@
|
||||||
import DropPasteHandler from "./components/DropPasteHandler.svelte";
|
import DropPasteHandler from "./components/DropPasteHandler.svelte";
|
||||||
import AddModal from "./components/AddModal.svelte";
|
import AddModal from "./components/AddModal.svelte";
|
||||||
import Store from "./views/Store.svelte";
|
import Store from "./views/Store.svelte";
|
||||||
import Surface from "./views/Surface.svelte";
|
|
||||||
import Setup from "./views/Setup.svelte";
|
import Setup from "./views/Setup.svelte";
|
||||||
|
|
||||||
import "./styles/main.scss";
|
import "./styles/main.scss";
|
||||||
|
@ -32,10 +31,6 @@
|
||||||
<Search query={decodeURIComponent(params.query)} />
|
<Search query={decodeURIComponent(params.query)} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path="/surface">
|
|
||||||
<Surface />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route path="/store">
|
<Route path="/store">
|
||||||
<Store />
|
<Store />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
|
@ -500,14 +500,6 @@
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if $entityInfo?.t === "Attribute"}
|
{#if $entityInfo?.t === "Attribute"}
|
||||||
<div class="buttons">
|
|
||||||
<div class="button">
|
|
||||||
<Link to="/surface?x={$entityInfo.c}">
|
|
||||||
{$i18n.t("Surface view")}
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<LabelBorder>
|
<LabelBorder>
|
||||||
<span slot="header"
|
<span slot="header"
|
||||||
>{$i18n.t("Used")} ({attributesUsed.length})</span
|
>{$i18n.t("Used")} ({attributesUsed.length})</span
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import UpObject from "../components/display/UpObject.svelte";
|
import UpObject from "./display/UpObject.svelte";
|
||||||
import api from "../lib/api";
|
import api from "../lib/api";
|
||||||
import Selector from "../components/utils/Selector.svelte";
|
import Selector from "./utils/Selector.svelte";
|
||||||
import { onMount } from "svelte";
|
import { onMount, tick } from "svelte";
|
||||||
import type { ZoomTransform } from "d3";
|
import type { ZoomTransform } from "d3";
|
||||||
import Spinner from "../components/utils/Spinner.svelte";
|
import Spinner from "./utils/Spinner.svelte";
|
||||||
import UpObjectCard from "../components/display/UpObjectCard.svelte";
|
import UpObjectCard from "./display/UpObjectCard.svelte";
|
||||||
import BlobPreview from "../components/display/BlobPreview.svelte";
|
import BlobPreview from "./display/BlobPreview.svelte";
|
||||||
import SurfacePoint from "../components/display/SurfacePoint.svelte";
|
import SurfacePoint from "./display/SurfacePoint.svelte";
|
||||||
import { i18n } from "../i18n";
|
import { i18n } from "../i18n";
|
||||||
import type { IValue } from "@upnd/upend/types";
|
import type { IValue } from "@upnd/upend/types";
|
||||||
import { useNavigate } from "svelte-navigator";
|
import debug from "debug";
|
||||||
const navigate = useNavigate();
|
const dbg = debug("kestrel:surface");
|
||||||
|
// import { useNavigate } from "svelte-navigator";
|
||||||
|
// const navigate = useNavigate();
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(
|
// const urlParams = new URLSearchParams(
|
||||||
window.location.href.substring(window.location.href.indexOf("?")),
|
// window.location.href.substring(window.location.href.indexOf("?")),
|
||||||
);
|
// );
|
||||||
|
|
||||||
export let x: string = urlParams.get("x");
|
export let x: string;
|
||||||
export let y: string = urlParams.get("y");
|
export let y: string | undefined = undefined; // TODO
|
||||||
$: if (x && y) navigate(`/surface?x=${x}&y=${y}`, { replace: true });
|
// $: if (x && y) navigate(`/surface?x=${x}&y=${y}`, { replace: true });
|
||||||
|
|
||||||
let viewMode = "point";
|
let viewMode = "point";
|
||||||
|
|
||||||
|
@ -27,9 +29,9 @@
|
||||||
let currentY = NaN;
|
let currentY = NaN;
|
||||||
|
|
||||||
let loaded = false;
|
let loaded = false;
|
||||||
|
let viewEl: HTMLElement | undefined;
|
||||||
let viewHeight = 0;
|
let viewHeight = 0;
|
||||||
let viewWidth = 0;
|
let viewWidth = 0;
|
||||||
let rootEl: HTMLElement | undefined;
|
|
||||||
|
|
||||||
interface IPoint {
|
interface IPoint {
|
||||||
address: string;
|
address: string;
|
||||||
|
@ -69,34 +71,54 @@
|
||||||
const d3 = await import("d3");
|
const d3 = await import("d3");
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
const view = d3.select(".view");
|
viewWidth = viewEl.clientWidth;
|
||||||
|
viewHeight = viewEl.clientHeight;
|
||||||
|
const selector = Array.from(viewEl.classList)
|
||||||
|
.map((c) => `.${c}`)
|
||||||
|
.join(" ");
|
||||||
|
|
||||||
|
dbg(
|
||||||
|
"Initializing Surface view for %s = %dx%d",
|
||||||
|
selector,
|
||||||
|
viewWidth,
|
||||||
|
viewHeight,
|
||||||
|
);
|
||||||
|
const view = d3.select(selector);
|
||||||
const svg = view.select("svg");
|
const svg = view.select("svg");
|
||||||
|
if (svg.empty()) {
|
||||||
|
throw new Error(
|
||||||
|
"Failed initializing Surface - couldn't locate SVG element",
|
||||||
|
);
|
||||||
|
}
|
||||||
svg.selectAll("*").remove();
|
svg.selectAll("*").remove();
|
||||||
|
|
||||||
const xScale = d3
|
const xScale = d3
|
||||||
.scaleLinear()
|
.scaleLinear()
|
||||||
.domain([0, viewWidth])
|
.domain([0, viewWidth / 10])
|
||||||
.range([0, viewWidth]);
|
.range([0, viewWidth]);
|
||||||
|
|
||||||
const xAxis = d3
|
|
||||||
.axisBottom(xScale)
|
|
||||||
.ticks(15)
|
|
||||||
.tickSize(viewHeight)
|
|
||||||
.tickPadding(5 - viewHeight);
|
|
||||||
|
|
||||||
const yScale = d3
|
const yScale = d3
|
||||||
.scaleLinear()
|
.scaleLinear()
|
||||||
.domain([0, viewHeight])
|
.domain([0, viewHeight / 10])
|
||||||
.range([viewHeight, 0]);
|
.range([viewHeight, 0]);
|
||||||
|
|
||||||
|
let xTicks = 10;
|
||||||
|
let yTicks = viewHeight / (viewWidth / xTicks);
|
||||||
|
|
||||||
|
const xAxis = d3
|
||||||
|
.axisBottom(xScale)
|
||||||
|
.ticks(xTicks)
|
||||||
|
.tickSize(viewHeight)
|
||||||
|
.tickPadding(5 - viewHeight);
|
||||||
|
|
||||||
const yAxis = d3
|
const yAxis = d3
|
||||||
.axisRight(yScale)
|
.axisRight(yScale)
|
||||||
.ticks(viewHeight / (viewWidth / 15))
|
.ticks(yTicks)
|
||||||
.tickSize(viewWidth)
|
.tickSize(viewWidth)
|
||||||
.tickPadding(5 - viewWidth);
|
.tickPadding(5 - viewWidth);
|
||||||
|
|
||||||
const gX = svg.append("g").attr("class", "axis axis--x").call(xAxis);
|
const gX = svg.append("g").call(xAxis);
|
||||||
const gY = svg.append("g").attr("class", "axis axis--y").call(yAxis);
|
const gY = svg.append("g").call(yAxis);
|
||||||
|
|
||||||
const zoom = d3
|
const zoom = d3
|
||||||
.zoom()
|
.zoom()
|
||||||
|
@ -108,12 +130,12 @@
|
||||||
.on("zoom", zoomed);
|
.on("zoom", zoomed);
|
||||||
|
|
||||||
function zoomed({ transform }: { transform: ZoomTransform }) {
|
function zoomed({ transform }: { transform: ZoomTransform }) {
|
||||||
const points = d3.select(".content");
|
const points = view.select(".content");
|
||||||
points.style(
|
points.style(
|
||||||
"transform",
|
"transform",
|
||||||
`translate(${transform.x}px, ${transform.y}px) scale(${transform.k})`,
|
`translate(${transform.x}px, ${transform.y}px) scale(${transform.k})`,
|
||||||
);
|
);
|
||||||
const allPoints = d3.selectAll(".point");
|
const allPoints = view.selectAll(".point");
|
||||||
allPoints.style("transform", `scale(${1 / transform.k})`);
|
allPoints.style("transform", `scale(${1 / transform.k})`);
|
||||||
|
|
||||||
gX.call(xAxis.scale(transform.rescaleX(xScale)));
|
gX.call(xAxis.scale(transform.rescaleX(xScale)));
|
||||||
|
@ -128,14 +150,14 @@
|
||||||
// not using offsetXY because `translate` transforms on .inner mess it up
|
// not using offsetXY because `translate` transforms on .inner mess it up
|
||||||
const viewBBox = (view.node() as HTMLElement).getBoundingClientRect();
|
const viewBBox = (view.node() as HTMLElement).getBoundingClientRect();
|
||||||
const [x, y] = d3
|
const [x, y] = d3
|
||||||
.zoomTransform(d3.select(".content").node() as HTMLElement)
|
.zoomTransform(view.select(".content").node() as HTMLElement)
|
||||||
.invert([ev.clientX - viewBBox.left, ev.clientY - viewBBox.top]);
|
.invert([ev.clientX - viewBBox.left, ev.clientY - viewBBox.top]);
|
||||||
|
|
||||||
currentX = xScale.invert(x);
|
currentX = xScale.invert(x);
|
||||||
currentY = yScale.invert(y);
|
currentY = yScale.invert(y);
|
||||||
});
|
});
|
||||||
|
|
||||||
d3.select(".view")
|
d3.select(selector)
|
||||||
.call(zoom)
|
.call(zoom)
|
||||||
.on("dblclick.zoom", (_ev: MouseEvent) => {
|
.on("dblclick.zoom", (_ev: MouseEvent) => {
|
||||||
selectorCoords = [currentX, currentY];
|
selectorCoords = [currentX, currentY];
|
||||||
|
@ -144,9 +166,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver(() => {
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
init();
|
tick().then(() => init());
|
||||||
});
|
});
|
||||||
resizeObserver.observe(rootEl);
|
resizeObserver.observe(viewEl);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function onSelectorInput(ev: CustomEvent<IValue>) {
|
async function onSelectorInput(ev: CustomEvent<IValue>) {
|
||||||
|
@ -167,16 +189,34 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="surface" bind:this={rootEl}>
|
<div class="surface">
|
||||||
<div class="header">
|
<div class="header ui">
|
||||||
<div class="axis-selector">
|
<div class="axis-selector">
|
||||||
X: <Selector type="attribute" bind:attribute={x} />
|
<div class="label">X</div>
|
||||||
|
<Selector type="attribute" bind:attribute={x} />
|
||||||
|
<div class="value">
|
||||||
|
{(Math.round(currentX * 100) / 100).toLocaleString("en", {
|
||||||
|
useGrouping: false,
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="axis-selector">
|
<div class="axis-selector">
|
||||||
Y: <Selector type="attribute" bind:attribute={y} />
|
<div class="label">Y</div>
|
||||||
|
<Selector type="attribute" bind:attribute={y} />
|
||||||
|
<div class="value">
|
||||||
|
{(Math.round(currentY * 100) / 100).toLocaleString("en", {
|
||||||
|
useGrouping: false,
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="view-mode-selector">
|
</div>
|
||||||
{$i18n.t("View as")}
|
<div class="view" class:loaded bind:this={viewEl}>
|
||||||
|
<div class="ui view-mode-selector">
|
||||||
|
<div class="label">
|
||||||
|
{$i18n.t("View as")}
|
||||||
|
</div>
|
||||||
<select bind:value={viewMode}>
|
<select bind:value={viewMode}>
|
||||||
<option value="point">{$i18n.t("Point")}</option>
|
<option value="point">{$i18n.t("Point")}</option>
|
||||||
<option value="link">{$i18n.t("Link")}</option>
|
<option value="link">{$i18n.t("Link")}</option>
|
||||||
|
@ -184,30 +224,6 @@
|
||||||
<!-- <option value="preview">{$i18n.t("Preview")}</option> -->
|
<!-- <option value="preview">{$i18n.t("Preview")}</option> -->
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="position">
|
|
||||||
{$i18n.t("Current position")}:
|
|
||||||
<div class="label">
|
|
||||||
<em>X:</em>
|
|
||||||
{x || "?"} = {(Math.round(currentX * 100) / 100).toLocaleString("en", {
|
|
||||||
useGrouping: false,
|
|
||||||
minimumFractionDigits: 2,
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
<div class="label">
|
|
||||||
<em>Y:</em>
|
|
||||||
{y || "?"} = {(Math.round(currentY * 100) / 100).toLocaleString("en", {
|
|
||||||
useGrouping: false,
|
|
||||||
minimumFractionDigits: 2,
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="view"
|
|
||||||
class:loaded
|
|
||||||
bind:clientWidth={viewWidth}
|
|
||||||
bind:clientHeight={viewHeight}
|
|
||||||
>
|
|
||||||
{#if !loaded}
|
{#if !loaded}
|
||||||
<div class="loading">
|
<div class="loading">
|
||||||
<Spinner centered="absolute" />
|
<Spinner centered="absolute" />
|
||||||
|
@ -263,23 +279,22 @@
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 2em;
|
flex-wrap: wrap;
|
||||||
padding: 1em;
|
gap: 1em;
|
||||||
border-bottom: 1px solid var(--foreground);
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 0.5em 0;
|
||||||
|
|
||||||
.axis-selector {
|
.axis-selector {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
|
||||||
|
|
||||||
.position {
|
.label {
|
||||||
display: flex;
|
font-size: 1rem;
|
||||||
gap: 1em;
|
&::after {
|
||||||
em {
|
content: ":";
|
||||||
font-weight: bold;
|
}
|
||||||
font-style: normal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,11 +328,37 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.view-mode-selector {
|
||||||
|
position: absolute;
|
||||||
|
top: 2rem;
|
||||||
|
right: 1.5em;
|
||||||
|
padding: 0.66em;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid var(--foreground-lighter);
|
||||||
|
background: var(--background);
|
||||||
|
opacity: 0.66;
|
||||||
|
transition: opacity 0.25s;
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&:not(.loaded) {
|
&:not(.loaded) {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.view-mode-selector {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5em;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
.loading {
|
.loading {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
|
@ -1,32 +1,28 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Address } from "@upnd/upend/types";
|
import type { Address } from "@upnd/upend/types";
|
||||||
import UpObject from "./UpObject.svelte";
|
import UpObject from "./UpObject.svelte";
|
||||||
import { useNavigate } from "svelte-navigator";
|
import UpLink from "./UpLink.svelte";
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
export let address: Address;
|
export let address: Address;
|
||||||
let popup = false;
|
let popup = false;
|
||||||
|
|
||||||
function visit() {
|
|
||||||
navigate(`/browse/${address}`);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
|
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div
|
<UpLink passthrough to={{ entity: address }}>
|
||||||
class="surface-point"
|
<div
|
||||||
class:popup
|
class="surface-point"
|
||||||
on:mouseover={() => (popup = true)}
|
class:popup
|
||||||
on:mouseleave={() => (popup = false)}
|
on:mouseover={() => (popup = true)}
|
||||||
on:click={visit}
|
on:mouseleave={() => (popup = false)}
|
||||||
>
|
>
|
||||||
{#if popup}
|
{#if popup}
|
||||||
<div class="popup-inner">
|
<div class="popup-inner">
|
||||||
<UpObject {address} />
|
<UpObject {address} />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
</UpLink>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@use "../../styles/colors.scss";
|
@use "../../styles/colors.scss";
|
||||||
|
|
|
@ -9,9 +9,11 @@
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
export let passthrough = false;
|
export let passthrough = false;
|
||||||
|
export let title: string | undefined = undefined;
|
||||||
export let to: {
|
export let to: {
|
||||||
entity?: Address;
|
entity?: Address;
|
||||||
attribute?: string;
|
attribute?: string;
|
||||||
|
surfaceAttribute?: string;
|
||||||
value?: { t: VALUE_TYPE; c: string };
|
value?: { t: VALUE_TYPE; c: string };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,6 +26,8 @@
|
||||||
api.getAddress({ attribute: to.attribute }).then((address) => {
|
api.getAddress({ attribute: to.attribute }).then((address) => {
|
||||||
targetHref = address;
|
targetHref = address;
|
||||||
});
|
});
|
||||||
|
} else if (to.surfaceAttribute) {
|
||||||
|
targetHref = `surface:${to.surfaceAttribute}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +62,7 @@
|
||||||
class:unresolved={targetHref === NOOP}
|
class:unresolved={targetHref === NOOP}
|
||||||
href="/#/browse/{targetHref}"
|
href="/#/browse/{targetHref}"
|
||||||
on:click|preventDefault={onClick}
|
on:click|preventDefault={onClick}
|
||||||
|
{title}
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -182,26 +182,38 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{#if banner && isFile}
|
{#if banner}
|
||||||
<div class="icon">
|
{#if $entityInfo?.t === "Attribute"}
|
||||||
<a
|
|
||||||
class="link-button"
|
|
||||||
href="{api.apiUrl}/raw/{address}"
|
|
||||||
download={inferredIds[0]}
|
|
||||||
title={$i18n.t("Download as file")}
|
|
||||||
>
|
|
||||||
<Icon name="download" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{#if $vaultInfo?.desktop}
|
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<IconButton
|
<UpLink
|
||||||
name="window-alt"
|
to={{ surfaceAttribute: $entityInfo.c }}
|
||||||
on:click={nativeOpen}
|
title={$i18n.t("Open on surface")}
|
||||||
title={$i18n.t("Open in default application...")}
|
>
|
||||||
/>
|
<Icon name="cross" />
|
||||||
|
</UpLink>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if isFile}
|
||||||
|
<div class="icon">
|
||||||
|
<a
|
||||||
|
class="link-button"
|
||||||
|
href="{api.apiUrl}/raw/{address}"
|
||||||
|
download={inferredIds[0]}
|
||||||
|
title={$i18n.t("Download as file")}
|
||||||
|
>
|
||||||
|
<Icon name="download" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{#if $vaultInfo?.desktop}
|
||||||
|
<div class="icon">
|
||||||
|
<IconButton
|
||||||
|
name="window-alt"
|
||||||
|
on:click={nativeOpen}
|
||||||
|
title={$i18n.t("Open in default application...")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
export let placeholder = "";
|
export let placeholder = "";
|
||||||
export let value = "";
|
export let value = "";
|
||||||
export let disabled = false;
|
export let disabled = false;
|
||||||
|
export let size: number | undefined = 7;
|
||||||
|
|
||||||
let focused = false;
|
let focused = false;
|
||||||
$: dispatch("focusChange", focused);
|
$: dispatch("focusChange", focused);
|
||||||
|
@ -29,6 +30,7 @@
|
||||||
on:input={onInput}
|
on:input={onInput}
|
||||||
on:focus={() => (focused = true)}
|
on:focus={() => (focused = true)}
|
||||||
on:blur={() => (focused = false)}
|
on:blur={() => (focused = false)}
|
||||||
|
size={Math.max(value.length, size)}
|
||||||
on:keydown
|
on:keydown
|
||||||
{disabled}
|
{disabled}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import Inspect from "../components/Inspect.svelte";
|
import Inspect from "../components/Inspect.svelte";
|
||||||
import CombineColumn from "../components/CombineColumn.svelte";
|
import CombineColumn from "../components/CombineColumn.svelte";
|
||||||
import GroupColumn from "../components/GroupColumn.svelte";
|
import GroupColumn from "../components/GroupColumn.svelte";
|
||||||
|
import SurfaceColumn from "../components/SurfaceColumn.svelte";
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
|
|
||||||
|
@ -118,6 +119,15 @@
|
||||||
>
|
>
|
||||||
<GroupColumn />
|
<GroupColumn />
|
||||||
</BrowseColumn>
|
</BrowseColumn>
|
||||||
|
{:else if address.startsWith("surface")}
|
||||||
|
<BrowseColumn
|
||||||
|
{index}
|
||||||
|
{only}
|
||||||
|
on:close={() => close(index)}
|
||||||
|
on:detail={(ev) => onDetailChanged(index, ev)}
|
||||||
|
>
|
||||||
|
<SurfaceColumn x={address.split(":")[1]} />
|
||||||
|
</BrowseColumn>
|
||||||
{:else}
|
{:else}
|
||||||
<BrowseColumn
|
<BrowseColumn
|
||||||
{address}
|
{address}
|
||||||
|
|
Loading…
Reference in New Issue