Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite schema builder as a stand-alone page #2685

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1,410 changes: 822 additions & 588 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
"update": "for dir in sites/*; do (cd $dir && npx ncu --interactive --format group); done",
"test-all": "for dir in sites/*; do (cd $dir && npm run test); done"
},
"devDependencies": {
},
"workspaces": [
"sites/*"
]
],
"dependencies": {
"svelte-pragmatic-list": "^0.0.1"
}
}
18 changes: 9 additions & 9 deletions sites/configs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
},
"dependencies": {
"@astrojs/mdx": "^3.1.3",
"@astrojs/netlify": "^5.4.0",
"@iconify-json/fa": "^1.1.8",
"@iconify-json/fa-brands": "^1.1.8",
"@iconify-json/file-icons": "^1.1.9",
"@iconify-json/line-md": "^1.1.38",
"@iconify-json/logos": "^1.1.43",
"@iconify-json/mdi": "^1.1.67",
"@iconify-json/octicon": "^1.1.56",
"@iconify/utils": "^2.1.25",
"@astrojs/netlify": "^5.5.0",
"@iconify-json/fa": "^1.1.9",
"@iconify-json/fa-brands": "^1.1.9",
"@iconify-json/file-icons": "^1.1.10",
"@iconify-json/line-md": "^1.1.39",
"@iconify-json/logos": "^1.1.44",
"@iconify-json/mdi": "^1.1.68",
"@iconify-json/octicon": "^1.1.57",
"@iconify/utils": "^2.1.30",
"svelte-exmarkdown": "^3.0.5"
}
}
18 changes: 9 additions & 9 deletions sites/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
},
"dependencies": {
"@astrojs/mdx": "^3.1.3",
"@astrojs/netlify": "^5.4.0",
"@iconify-json/fa": "^1.1.8",
"@iconify-json/fa-brands": "^1.1.8",
"@iconify-json/file-icons": "^1.1.9",
"@iconify-json/line-md": "^1.1.38",
"@iconify-json/logos": "^1.1.43",
"@iconify-json/mdi": "^1.1.67",
"@iconify-json/octicon": "^1.1.56",
"@iconify/utils": "^2.1.25",
"@astrojs/netlify": "^5.5.0",
"@iconify-json/fa": "^1.1.9",
"@iconify-json/fa-brands": "^1.1.9",
"@iconify-json/file-icons": "^1.1.10",
"@iconify-json/line-md": "^1.1.39",
"@iconify-json/logos": "^1.1.44",
"@iconify-json/mdi": "^1.1.68",
"@iconify-json/octicon": "^1.1.57",
"@iconify/utils": "^2.1.30",
"svelte-exmarkdown": "^3.0.5"
}
}
42 changes: 21 additions & 21 deletions sites/main-site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,32 @@
"test": "playwright test"
},
"dependencies": {
"@astro-community/astro-embed-youtube": "^0.5.2",
"@astro-community/astro-embed-youtube": "^0.5.3",
"@astrojs/internal-helpers": "^0.4.1",
"@astrojs/markdown-remark": "^5.2.0",
"@astrojs/mdx": "^3.1.3",
"@astrojs/netlify": "^5.4.0",
"@astrojs/netlify": "^5.5.0",
"@astrojs/partytown": "^2.1.1",
"@astrojs/rss": "^4.0.7",
"@astrojs/sitemap": "^3.1.6",
"@astrojs/svelte": "^5.7.0",
"@astropub/md": "https://gitpkg.vercel.app/mashehu/astropub-md/packages/md?main",
"@docsearch/css": "^3.6.1",
"@docsearch/js": "^3.6.1",
"@fontsource-variable/inter": "^5.0.19",
"@fontsource-variable/inter": "^5.0.20",
"@fontsource-variable/maven-pro": "^5.0.19",
"@iconify-json/fa": "^1.1.8",
"@iconify-json/fa-brands": "^1.1.8",
"@iconify-json/file-icons": "^1.1.9",
"@iconify-json/line-md": "^1.1.38",
"@iconify-json/logos": "^1.1.43",
"@iconify-json/mdi": "^1.1.67",
"@iconify-json/octicon": "^1.1.56",
"@iconify-json/simple-icons": "^1.1.109",
"@iconify/utils": "^2.1.25",
"@nanostores/persistent": "^0.10.1",
"@iconify-json/fa": "^1.1.9",
"@iconify-json/fa-brands": "^1.1.9",
"@iconify-json/file-icons": "^1.1.10",
"@iconify-json/line-md": "^1.1.39",
"@iconify-json/logos": "^1.1.44",
"@iconify-json/mdi": "^1.1.68",
"@iconify-json/octicon": "^1.1.57",
"@iconify-json/simple-icons": "^1.1.113",
"@iconify/utils": "^2.1.30",
"@nanostores/persistent": "^0.10.2",
"@octokit/types": "^13.5.0",
"astro": "^4.12.2",
"astro": "^4.13.4",
"astro-icon": "^1.1.0",
"astro-remark-description": "^1.1.2",
"bootstrap": "^5.3.3",
Expand All @@ -59,9 +59,9 @@
"katex": "^0.16.11",
"kleur": "^4.1.5",
"leaflet": "^1.9.4",
"lite-youtube-embed": "^0.3.2",
"lite-youtube-embed": "^0.3.3",
"mermaid": "^10.9.1",
"nanostores": "^0.10.3",
"nanostores": "^0.11.2",
"octokit": "^4.0.2",
"party-js": "^2.2.0",
"path-to-regexp": "^6.2.1",
Expand All @@ -83,24 +83,24 @@
"satori": "^0.10.14",
"satori-html": "^0.3.2",
"sharp": "^0.33.4",
"shiki": "^1.11.0",
"shiki": "^1.13.0",
"shikiji": "^0.10.2",
"string-width": "^7.2.0",
"svelte": "^4.2.18",
"svelte-confetti": "^1.4.0",
"svelte-exmarkdown": "^3.0.5",
"svelte-fast-marquee": "^0.7.0",
"ts-dedent": "^2.2.0",
"typescript": "^5.5.3",
"typescript": "^5.5.4",
"unist-util-visit": "^5.0.0",
"vite": "^5.3.4",
"yaml": "^2.4.5",
"vite": "^5.4.0",
"yaml": "^2.5.0",
"yoga-wasm-web": "^0.3.3",
"youtube-player": "^5.6.0",
"zod": "^3.23.8"
},
"devDependencies": {
"@playwright/test": "^1.45.2",
"@playwright/test": "^1.46.0",
"@rollup/plugin-yaml": "4.1.2",
"@types/leaflet": "1.9.12",
"@types/node": "^20.14.11",
Expand Down
2 changes: 0 additions & 2 deletions sites/main-site/src/components/navbar/Navbar.astro
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import IconSocial from '@components/IconSocial.astro';
import ThemeSwitch from '@components/ThemeSwitch.svelte';
import { Icon } from 'astro-icon/components';
import Search from '@components/navbar/Search.svelte';
import { findCurrentGroup } from '@utils/functions';
import BlogPostLabel from '@components/navbar/BlogPostLabel.svelte';
import type { SidebarEntry } from '@utils/types';
import { getCollection, type CollectionEntry } from 'astro:content';
import type { SidebarEntry } from '@utils/types';

Expand Down
38 changes: 32 additions & 6 deletions sites/main-site/src/components/schema/SchemaListing.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import { currentHeading } from '@components/store';

export let schema;
// get schema version which is the second last element of the array
let schemaVersion = schema['$schema'].split('/').slice(-2)[0];

onMount(() => {
const observer = new IntersectionObserver(
(entries) => {
Expand All @@ -17,17 +20,40 @@
rootMargin: '0px 0px -92% 0px',
},
);
Object.entries(schema.definitions).forEach((heading) => {
const element = document.querySelector('#' + heading[0].replaceAll('_', '-'));
observer.observe(element);
});
if (schemaVersion === 'draft-07') {
Object.entries(schema.definitions).forEach((heading) => {
const element = document.querySelector('#' + heading[0].replaceAll('_', '-'));
observer.observe(element);
});
} else {
Object.entries(schema['$defs']).forEach((heading) => {
const element = document.querySelector('#' + heading[0].replaceAll('_', '-'));
observer.observe(element);
});
}
});
</script>

<div class="schema-listing">
{#if Object.entries(schema.definitions).length > 0}
{#if schemaVersion === 'draft-07'}
{#if Object.entries(schema.definitions).length > 0}
<div class="d-flex flex-column">
{#each Object.entries(schema.definitions) as [id, definition] (id)}
<SchemaListingGroup {definition} {id} />
{/each}
</div>
{:else}
<div class="alert alert-warning mt-3" role="alert">
<h4 class="text-warning">No nextflow_schema.json file found!</h4>
<p>
It seems like there is no nextflow_schema.json file with parameters defined for this version of the
pipeline. Try a newer version.
</p>
</div>
{/if}
{:else if Object.entries(schema['$defs']).length > 0}
<div class="d-flex flex-column">
{#each Object.entries(schema.definitions) as [id, definition] (id)}
{#each Object.entries(schema['$defs']) as [id, definition] (id)}
<SchemaListingGroup {definition} {id} />
{/each}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

const pattern = property.pattern;
let longPattern = [];
// explicitely handle patterns which are an enum work around, i.e. they have multiple values, eg. "^(foo|bar)$"
// explicitly handle patterns which are an enum work around, i.e. they have multiple values, eg. "^(foo|bar)$"
if (
pattern &&
pattern.startsWith('^(') &&
Expand All @@ -26,14 +26,14 @@
class:collapse={property.hidden}
class:show={$showHidden}
>
<div id={title} class="col-12 col-md-3 title border-right border-secondary text-nowrap p-0 pe-2">
<div id={title} class="col-12 col-md-4 title border-right border-secondary text-nowrap p-0 pe-2">
<a class="text-decoration-none d-block overflow-x-scroll" aria-hidden="true" tabindex="-1" href={'#' + title}
><i class="ms-1 fas invisible" aria-hidden="true" />
<span class="">
{#if property.fa_icon}
<i class="fa fa-fw {property.fa_icon}" />
{/if}
<code>--{title}</code>
<code>{title}</code><span class="opacity-50 font-monospace small">:{property.type}</span>
</span>
</a>
</div>
Expand All @@ -47,9 +47,6 @@
{#if property.required}
<span class="badge text-bg-warning mb-1">required</span>
{/if}
<div class="text-body-secondary">
type: <code>{property.type}</code>
</div>
{#if property.enum}
<select class="form-select mt-2" value={property.default} aria-label="Parameter enum options">
{#each property.enum as value}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<script lang="ts">
import { onMount } from 'svelte';

// import { dnd } from 'svelte-pragmatic-list';
import SchemaBuilderListingGroup from './SchemaBuilderListingGroup.svelte';
import SchemaBuilderToolbar from './SchemaBuilderToolbar.svelte';

import CopyButton from '@components/CopyButton.svelte';
let schema = {};

let defName = 'definitions';
let schema_path = '';

let status = 'loading';
let collapseGroups = false;

// rename key in the schema

// post schema to the server
const postSchema = async (postStatus: string) => {
const response = await fetch(`http://localhost:8000/process-schema`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
message: 'Schema created successfully',
},
body: JSON.stringify({ status: postStatus, schema, schema_path }),
});
const data = await response.json();
if (data.status === 'web_builder_edited') {
status = 'saved';
}
};

onMount(async () => {
// read schema_path from URL
const url = new URL(window.location.href);
schema_path = url.searchParams.get('schema_path') || '';
if (!schema_path) {
console.error('No schema_path found in the URL');
return;
}
try {
const response = await fetch(`http://localhost:8000/process-schema?schema_path=${schema_path}`);
const data = await response.json();

schema = data.data;
status = 'loaded';
} catch (error) {
console.error('Error fetching schema:', error);
status = 'loaded';
// Handle the error, maybe show an error message to the user
}
});
const removeGroup = (name) => {
let result = confirm('Are you sure you want to remove this group?');
if (!result) return;
delete schema?.definitions[name];
schema = { ...schema };
};
</script>

<div>
<SchemaBuilderToolbar bind:schema>
<div class="d-flex">
<button
class="btn btn-outline-secondary"
on:click={() => {
collapseGroups = !collapseGroups;
}}>Collapse Groups</button
>
</div>
<button
id="finish"
class="btn btn-primary"
class:disabled={status !== 'loaded'}
on:click={() => {
postSchema('web_builder_edited');
}}>Finish</button
>
</SchemaBuilderToolbar>

<div class="d-flex flex-column flex-xxl-row">
<div class="w-75">
<div class="border rounded-md" class:border-success={status === 'saved'}>
{#if status === 'loading'}
<p>Loading schema...</p>
{:else if status === 'loaded'}
<div class="p-2" class:collapse={collapseGroups}>
{#each Object.keys(schema[defName]) as key (key)}
<SchemaBuilderListingGroup name={key} {schema}>
<button
slot="delete-group"
class="btn btn-outline-danger delete-btn"
on:click={() => removeGroup(key)}
>
<i class="fas fa-trash"></i>
</button>
</SchemaBuilderListingGroup>
{/each}
<div data-dnd-indicator hidden style="height: 20px; background-color: red; width: 100%;"></div>
</div>
{:else if (status = 'saved')}
<p class="m-2">Schema saved! See terminal log for more details.</p>
{/if}
</div>
</div>
<figure class="w-25">
<figcaption
data-rehype-pretty-code-title=""
data-language="json"
class="d-flex align-items-center justify-content-between"
>
<span><i class="fa-solid fa-database ms-1 me-2"></i>nf-params.json</span><CopyButton
text={JSON.stringify(schema, null, 2)}
label="Copy Schema <i class='fa-regular fa-clipboard'></i>"
copiedLabel="Copied Schema <i class='fa-regular px-1 fa-clipboard-check' />"
classes={'m-2 copy-code-button btn btn-sm btn-outline-secondary opacity-50'}
copiedClasses={'m-2 copy-code-button btn btn-sm btn-outline-success'}
/>
</figcaption>
<pre class="text-secondary p-0">
<code class="" data-language="json">
{JSON.stringify(schema, null, 2)}
</code>
</pre>
</figure>
</div>
</div>

<style lang="scss">
.delete-btn:not(:hover) {
color: var(--bs-tertiary-color);
border-color: var(--bs-tertiary-color);
}
</style>
Loading
Loading