Merge branch 'merge-outputs'
This commit is contained in:
commit
59cf71c140
27
src/lib/actions/clipboard.js
Normal file
27
src/lib/actions/clipboard.js
Normal file
@ -0,0 +1,27 @@
|
||||
// stolen from svelte-copy-clipboard-action
|
||||
|
||||
export function clipboard(node, { trigger = "click", text = "" } = {}) {
|
||||
const handle = async (e) => {
|
||||
await navigator.clipboard.writeText(text).then(
|
||||
() =>
|
||||
node.dispatchEvent(
|
||||
new CustomEvent("copied", { detail: { clipboard: text } })
|
||||
),
|
||||
(e) =>
|
||||
node.dispatchEvent(new CustomEvent("error", { detail: { error: e } }))
|
||||
);
|
||||
};
|
||||
|
||||
node.addEventListener(trigger, handle, true);
|
||||
|
||||
return {
|
||||
update: (params) => {
|
||||
if (params.trigger !== undefined) trigger = params.trigger;
|
||||
|
||||
if (params.text !== undefined) text = params.text;
|
||||
},
|
||||
destroy() {
|
||||
node.removeEventListener(trigger, handle, true);
|
||||
},
|
||||
};
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import ship from "./ship";
|
||||
import { browser } from "$app/environment";
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
export type Api = ReturnType<typeof ship.createStore>;
|
||||
|
||||
@ -14,12 +15,17 @@ export const createApi = () => {
|
||||
|
||||
api.dispatch.restore(state);
|
||||
|
||||
const svelteStore = writable(state);
|
||||
|
||||
if (browser) {
|
||||
api.subscribe(() => {
|
||||
console.log("saving...", api.getState());
|
||||
localStorage.setItem("ship", JSON.stringify(api.getState()));
|
||||
const state = api.getState();
|
||||
svelteStore.set(state);
|
||||
localStorage.setItem("ship", JSON.stringify(state));
|
||||
});
|
||||
}
|
||||
|
||||
api.svelteStore = svelteStore;
|
||||
|
||||
return api;
|
||||
};
|
||||
|
4
src/params/outputFormat.js
Normal file
4
src/params/outputFormat.js
Normal file
@ -0,0 +1,4 @@
|
||||
/** @type {import('@sveltejs/kit').ParamMatcher} */
|
||||
export function match(param) {
|
||||
return ["json", "yaml"].includes(param);
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
<nav class="m l left">
|
||||
<!-- set them as active -->
|
||||
<a href="/export/json">
|
||||
<i>output</i>
|
||||
<span>json</span>
|
||||
|
6
src/routes/export/[format=outputFormat]/+page.js
Normal file
6
src/routes/export/[format=outputFormat]/+page.js
Normal file
@ -0,0 +1,6 @@
|
||||
/** @type {import('./$types').PageLoad} */
|
||||
export function load({ params }) {
|
||||
return {
|
||||
format: params.format,
|
||||
};
|
||||
}
|
21
src/routes/export/[format=outputFormat]/+page.svelte
Normal file
21
src/routes/export/[format=outputFormat]/+page.svelte
Normal file
@ -0,0 +1,21 @@
|
||||
<Serialized data={serializedShip} format={data.format} />
|
||||
|
||||
<script>
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import Serialized from "./Serialized.svelte";
|
||||
|
||||
const api = getContext("api");
|
||||
|
||||
let shipData = api.svelteStore;
|
||||
export let data;
|
||||
|
||||
const serialize = async (data, format) => {
|
||||
if (format === "json") return JSON.stringify(data, null, 2);
|
||||
|
||||
return import("yaml").then(({ stringify }) => stringify(data));
|
||||
};
|
||||
|
||||
let serializedShip;
|
||||
$: serialize($shipData, data.format).then((s) => (serializedShip = s));
|
||||
</script>
|
@ -1,25 +1,21 @@
|
||||
<article>
|
||||
<nav>
|
||||
<button
|
||||
use:clipboard={{ text: shipJson }}
|
||||
use:clipboard={{ text: data }}
|
||||
on:copied={copied}
|
||||
on:error={copyError}>{copyLabel} <i>content_paste</i></button
|
||||
>
|
||||
<button on:click={handleSave}>download <i>download</i></button>
|
||||
</nav>
|
||||
<pre><code>{shipJson}</code></pre>
|
||||
<pre><code>{data}</code></pre>
|
||||
<a hidden {href} {download} bind:this={fileDownload} />
|
||||
</article>
|
||||
|
||||
<script>
|
||||
import { getContext } from "svelte";
|
||||
import { clipboard } from "svelte-copy-clipboard-action";
|
||||
import { clipboard } from "$lib/actions/clipboard.js";
|
||||
|
||||
// TODO copy
|
||||
const api = getContext("api");
|
||||
|
||||
let shipData = api.getState();
|
||||
api.subscribe(() => (shipDate = api.getState()));
|
||||
export let data = "Loading...";
|
||||
export let format;
|
||||
|
||||
let copyLabel = "clipboard";
|
||||
|
||||
@ -33,10 +29,8 @@
|
||||
setTimeout(() => (copyLabel = "clipboard"), 2000);
|
||||
};
|
||||
|
||||
$: shipJson = JSON.stringify(shipData, null, 2);
|
||||
|
||||
$: href = "data:text/plain;charset=utf-8," + encodeURIComponent(shipJson);
|
||||
$: download = (shipData?.identification?.shipClass || "ship") + ".json";
|
||||
$: href = "data:text/plain;charset=utf-8," + encodeURIComponent(data);
|
||||
$: download = (data?.identification?.shipClass || "ship") + "." + format;
|
||||
|
||||
let fileDownload;
|
||||
|
14
src/routes/export/[format=outputFormat]/Serialized.test.js
Normal file
14
src/routes/export/[format=outputFormat]/Serialized.test.js
Normal file
@ -0,0 +1,14 @@
|
||||
import { render } from "@testing-library/svelte";
|
||||
import "@testing-library/jest-dom";
|
||||
|
||||
import Serialized from "./Serialized.svelte";
|
||||
|
||||
test("basic", () => {
|
||||
const { getByText } = render(Serialized, {
|
||||
props: {
|
||||
data: "hello world",
|
||||
format: "json",
|
||||
},
|
||||
});
|
||||
expect(getByText("hello world")).toBeInTheDocument();
|
||||
});
|
@ -1,60 +0,0 @@
|
||||
<article>
|
||||
<nav>
|
||||
<button
|
||||
use:clipboard={{ text: shipJson }}
|
||||
on:copied={copied}
|
||||
on:error={copyError}>{copyLabel} <i>content_paste</i></button
|
||||
>
|
||||
<button on:click={handleSave}>download <i>download</i></button>
|
||||
</nav>
|
||||
<pre><code>{shipJson}</code></pre>
|
||||
<a hidden {href} {download} bind:this={fileDownload} />
|
||||
</article>
|
||||
|
||||
<script>
|
||||
import { getContext } from "svelte";
|
||||
import { clipboard } from "svelte-copy-clipboard-action";
|
||||
import { stringify } from "yaml";
|
||||
|
||||
// TODO copy
|
||||
const api = getContext("api");
|
||||
|
||||
let shipData = api.getState();
|
||||
api.subscribe(() => (shipDate = api.getState()));
|
||||
|
||||
let copyLabel = "clipboard";
|
||||
|
||||
const copied = () => {
|
||||
copyLabel = "copied!";
|
||||
setTimeout(() => (copyLabel = "clipboard"), 2000);
|
||||
};
|
||||
|
||||
const copyError = () => {
|
||||
copyLabel = "error copying";
|
||||
setTimeout(() => (copyLabel = "clipboard"), 2000);
|
||||
};
|
||||
|
||||
$: shipJson = stringify(shipData, null, 2);
|
||||
|
||||
$: href = "data:text/plain;charset=utf-8," + encodeURIComponent(shipJson);
|
||||
$: download = (shipData?.identification?.shipClass || "ship") + ".yml";
|
||||
|
||||
let fileDownload;
|
||||
|
||||
function handleSave() {
|
||||
fileDownload?.click();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
article {
|
||||
background-color: var(--primary-container);
|
||||
}
|
||||
button {
|
||||
font-size: var(--font-scale-10);
|
||||
}
|
||||
nav {
|
||||
position: absolute;
|
||||
right: 5em;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user