Migrate config, migrate analysis plotselection

This commit is contained in:
Christoph Kluge 2025-06-16 17:09:02 +02:00
parent d6d92071bf
commit 6a6dca3fce
16 changed files with 224 additions and 199 deletions

View File

@ -14,15 +14,18 @@
import SupportSettings from "./config/SupportSettings.svelte"; import SupportSettings from "./config/SupportSettings.svelte";
import AdminSettings from "./config/AdminSettings.svelte"; import AdminSettings from "./config/AdminSettings.svelte";
export let isAdmin; /* Svelte 5 Props */
export let isSupport; let {
export let isApi; isAdmin,
export let username; isSupport,
export let ncontent; isApi,
username,
ncontent,
} = $props();
</script> </script>
{#if isAdmin} {#if isAdmin}
<Card style="margin-bottom: 1.5em;"> <Card style="margin-bottom: 1.5rem;">
<CardHeader> <CardHeader>
<CardTitle class="mb-1">Admin Options</CardTitle> <CardTitle class="mb-1">Admin Options</CardTitle>
</CardHeader> </CardHeader>
@ -31,7 +34,7 @@
{/if} {/if}
{#if isSupport || isAdmin} {#if isSupport || isAdmin}
<Card style="margin-bottom: 1.5em;"> <Card style="margin-bottom: 1.5rem;">
<CardHeader> <CardHeader>
<CardTitle class="mb-1">Support Options</CardTitle> <CardTitle class="mb-1">Support Options</CardTitle>
</CardHeader> </CardHeader>

View File

@ -21,10 +21,14 @@
} from "@sveltestrap/sveltestrap"; } from "@sveltestrap/sveltestrap";
import { gql, getContextClient, mutationStore } from "@urql/svelte"; import { gql, getContextClient, mutationStore } from "@urql/svelte";
export let availableMetrics; /* Svelte 5 Props */
export let metricsInHistograms; let {
export let metricsInScatterplots; availableMetrics,
metricsInHistograms = $bindable(),
metricsInScatterplots = $bindable(),
} = $props();
/* Const Init */
const client = getContextClient(); const client = getContextClient();
const updateConfigurationMutation = ({ name, value }) => { const updateConfigurationMutation = ({ name, value }) => {
return mutationStore({ return mutationStore({
@ -38,11 +42,13 @@
}); });
}; };
let isHistogramConfigOpen = false, /* State Init */
isScatterPlotConfigOpen = false; let isHistogramConfigOpen = $state(false);
let selectedMetric1 = null, let isScatterPlotConfigOpen = $state(false);
selectedMetric2 = null; let selectedMetric1 = $state(null);
let selectedMetric2 = $state(null);
/* Functions */
function updateConfiguration(data) { function updateConfiguration(data) {
updateConfigurationMutation({ updateConfigurationMutation({
name: data.name, name: data.name,
@ -55,12 +61,12 @@
} }
</script> </script>
<Button outline on:click={() => (isHistogramConfigOpen = true)}> <Button outline onclick={() => (isHistogramConfigOpen = true)}>
<Icon name="" /> <Icon name="" />
Select Plots for Histograms Select Plots for Histograms
</Button> </Button>
<Button outline on:click={() => (isScatterPlotConfigOpen = true)}> <Button outline onclick={() => (isScatterPlotConfigOpen = true)}>
<Icon name="" /> <Icon name="" />
Select Plots in Scatter Plots Select Plots in Scatter Plots
</Button> </Button>
@ -78,7 +84,7 @@
type="checkbox" type="checkbox"
bind:group={metricsInHistograms} bind:group={metricsInHistograms}
value={metric} value={metric}
on:change={() => onchange={() =>
updateConfiguration({ updateConfiguration({
name: "analysis_view_histogramMetrics", name: "analysis_view_histogramMetrics",
value: metricsInHistograms, value: metricsInHistograms,
@ -91,7 +97,7 @@
</ListGroup> </ListGroup>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button color="primary" on:click={() => (isHistogramConfigOpen = false)}> <Button color="primary" onclick={() => (isHistogramConfigOpen = false)}>
Close Close
</Button> </Button>
</ModalFooter> </ModalFooter>
@ -112,7 +118,7 @@
style="float: right;" style="float: right;"
outline outline
color="danger" color="danger"
on:click={() => { onclick={() => {
metricsInScatterplots = metricsInScatterplots.filter( metricsInScatterplots = metricsInScatterplots.filter(
(p) => pair != p, (p) => pair != p,
); );
@ -146,7 +152,7 @@
<Button <Button
outline outline
disabled={selectedMetric1 == null || selectedMetric2 == null} disabled={selectedMetric1 == null || selectedMetric2 == null}
on:click={() => { onclick={() => {
metricsInScatterplots = [ metricsInScatterplots = [
...metricsInScatterplots, ...metricsInScatterplots,
[selectedMetric1, selectedMetric2], [selectedMetric1, selectedMetric2],
@ -164,7 +170,7 @@
</InputGroup> </InputGroup>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button color="primary" on:click={() => (isScatterPlotConfigOpen = false)}> <Button color="primary" onclick={() => (isScatterPlotConfigOpen = false)}>
Close Close
</Button> </Button>
</ModalFooter> </ModalFooter>

View File

@ -12,13 +12,17 @@
import Options from "./admin/Options.svelte"; import Options from "./admin/Options.svelte";
import NoticeEdit from "./admin/NoticeEdit.svelte"; import NoticeEdit from "./admin/NoticeEdit.svelte";
export let ncontent; /* Svelte 5 Props */
let { ncontent } = $props();
let users = [];
let roles = [];
/* Const Init*/
const ccconfig = getContext("cc-config"); const ccconfig = getContext("cc-config");
/* State Init */
let users = $state([]);
let roles = $state([]);
/* Functions */
function getUserList() { function getUserList() {
fetch("/config/users/?via-ldap=false&not-just-user=true") fetch("/config/users/?via-ldap=false&not-just-user=true")
.then((res) => res.json()) .then((res) => res.json())
@ -40,21 +44,22 @@
getValidRoles(); getValidRoles();
} }
/* on Mount */
onMount(() => initAdmin()); onMount(() => initAdmin());
</script> </script>
<Row cols={2} class="p-2 g-2"> <Row cols={2} class="p-2 g-2">
<Col class="mb-1"> <Col class="mb-1">
<AddUser {roles} on:reload={getUserList} /> <AddUser {roles} reloadUser={() => getUserList()} />
</Col> </Col>
<Col class="mb-1"> <Col class="mb-1">
<ShowUsers on:reload={getUserList} bind:users /> <ShowUsers reloadUser={() => getUserList()} bind:users />
</Col> </Col>
<Col> <Col>
<EditRole {roles} on:reload={getUserList} /> <EditRole {roles} reloadUser={() => getUserList()} />
</Col> </Col>
<Col> <Col>
<EditProject on:reload={getUserList} /> <EditProject reloadUser={() => getUserList()} />
</Col> </Col>
<Options config={ccconfig}/> <Options config={ccconfig}/>
<NoticeEdit {ncontent}/> <NoticeEdit {ncontent}/>

View File

@ -12,17 +12,26 @@
import PlotRenderOptions from "./user/PlotRenderOptions.svelte"; import PlotRenderOptions from "./user/PlotRenderOptions.svelte";
import PlotColorScheme from "./user/PlotColorScheme.svelte"; import PlotColorScheme from "./user/PlotColorScheme.svelte";
export let username /* Svelte 5 Props */
export let isApi let {
username,
isApi
} = $props();
/* Const Init */
const ccconfig = getContext("cc-config"); const ccconfig = getContext("cc-config");
let message = { msg: "", target: "", color: "#d63384" };
let displayMessage = false;
let cbmode = ccconfig?.plot_general_colorblindMode || false;
async function handleSettingSubmit(event) { /* State Init */
const selector = event.detail.selector let message = $state({ msg: "", target: "", color: "#d63384" });
const target = event.detail.target let displayMessage = $state(false);
let cbmode = $state(ccconfig?.plot_general_colorblindMode || false);
/* Functions */
async function handleSettingSubmit(event, setting) {
event.preventDefault();
const selector = setting.selector
const target = setting.target
let form = document.querySelector(selector); let form = document.querySelector(selector);
let formData = new FormData(form); let formData = new FormData(form);
try { try {
@ -53,6 +62,6 @@
} }
</script> </script>
<UserOptions config={ccconfig} {username} {isApi} bind:message bind:displayMessage on:update-config={(e) => handleSettingSubmit(e)}/> <UserOptions config={ccconfig} {username} {isApi} bind:message bind:displayMessage updateSetting={(e, newSetting) => handleSettingSubmit(e, newSetting)}/>
<PlotRenderOptions config={ccconfig} bind:message bind:displayMessage on:update-config={(e) => handleSettingSubmit(e)}/> <PlotRenderOptions config={ccconfig} bind:message bind:displayMessage updateSetting={(e, newSetting) => handleSettingSubmit(e, newSetting)}/>
<PlotColorScheme config={ccconfig} bind:cbmode bind:message bind:displayMessage on:update-config={(e) => handleSettingSubmit(e)}/> <PlotColorScheme config={ccconfig} bind:cbmode bind:message bind:displayMessage updateSetting={(e, newSetting) => handleSettingSubmit(e, newSetting)}/>

View File

@ -10,17 +10,19 @@
<script> <script>
import { Button, Card, CardTitle } from "@sveltestrap/sveltestrap"; import { Button, Card, CardTitle } from "@sveltestrap/sveltestrap";
import { createEventDispatcher } from "svelte";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
const dispatch = createEventDispatcher(); /* Svelte 5 Props */
let { roles, reloadUser } = $props();
let message = { msg: "", color: "#d63384" }; /* State Init */
let displayMessage = false; let message = $state({ msg: "", color: "#d63384" });
let displayMessage = $state(false);
export let roles; /* Functions */
async function handleUserSubmit(event) {
event.preventDefault();
async function handleUserSubmit() {
let form = document.querySelector("#create-user-form"); let form = document.querySelector("#create-user-form");
let formData = new FormData(form); let formData = new FormData(form);
@ -29,7 +31,7 @@
if (res.ok) { if (res.ok) {
let text = await res.text(); let text = await res.text();
popMessage(text, "#048109"); popMessage(text, "#048109");
reloadUserList(); reloadUser();
form.reset(); form.reset();
} else { } else {
let text = await res.text(); let text = await res.text();
@ -47,10 +49,6 @@
displayMessage = false; displayMessage = false;
}, 3500); }, 3500);
} }
function reloadUserList() {
dispatch("reload");
}
</script> </script>
<Card> <Card>
@ -60,7 +58,7 @@
action="/config/users/" action="/config/users/"
class="card-body" class="card-body"
autocomplete="off" autocomplete="off"
on:submit|preventDefault={handleUserSubmit} onsubmit={(e) => handleUserSubmit(e)}
> >
<CardTitle class="mb-3">Create User</CardTitle> <CardTitle class="mb-3">Create User</CardTitle>
<div class="mb-3"> <div class="mb-3">

View File

@ -7,15 +7,19 @@
<script> <script>
import { Card, CardTitle, CardBody } from "@sveltestrap/sveltestrap"; import { Card, CardTitle, CardBody } from "@sveltestrap/sveltestrap";
import { createEventDispatcher } from "svelte";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
const dispatch = createEventDispatcher(); /* Svelte 5 Props */
let { reloadUser } = $props();
let message = { msg: "", color: "#d63384" }; /* State Init */
let displayMessage = false; let message = $state({ msg: "", color: "#d63384" });
let displayMessage = $state(false);
/* Functions */
async function handleAddProject(event) {
event.preventDefault();
async function handleAddProject() {
const username = document.querySelector("#project-username").value; const username = document.querySelector("#project-username").value;
const project = document.querySelector("#project-id").value; const project = document.querySelector("#project-id").value;
@ -36,7 +40,7 @@
if (res.ok) { if (res.ok) {
let text = await res.text(); let text = await res.text();
popMessage(text, "#048109"); popMessage(text, "#048109");
reloadUserList(); reloadUser();
} else { } else {
let text = await res.text(); let text = await res.text();
throw new Error("Response Code " + res.status + "-> " + text); throw new Error("Response Code " + res.status + "-> " + text);
@ -46,7 +50,9 @@
} }
} }
async function handleRemoveProject() { async function handleRemoveProject(event) {
event.preventDefault();
const username = document.querySelector("#project-username").value; const username = document.querySelector("#project-username").value;
const project = document.querySelector("#project-id").value; const project = document.querySelector("#project-id").value;
@ -67,7 +73,7 @@
if (res.ok) { if (res.ok) {
let text = await res.text(); let text = await res.text();
popMessage(text, "#048109"); popMessage(text, "#048109");
reloadUserList(); reloadUser();
} else { } else {
let text = await res.text(); let text = await res.text();
throw new Error("Response Code " + res.status + "-> " + text); throw new Error("Response Code " + res.status + "-> " + text);
@ -84,10 +90,6 @@
displayMessage = false; displayMessage = false;
}, 3500); }, 3500);
} }
function reloadUserList() {
dispatch("reload");
}
</script> </script>
<Card> <Card>
@ -108,19 +110,17 @@
placeholder="project-id" placeholder="project-id"
id="project-id" id="project-id"
/> />
<!-- PreventDefault on Sveltestrap-Button more complex to achieve than just use good ol' html button -->
<!-- see: https://stackoverflow.com/questions/69630422/svelte-how-to-use-event-modifiers-in-my-own-components -->
<button <button
class="btn btn-primary" class="btn btn-primary"
type="button" type="button"
id="add-project-button" id="add-project-button"
on:click|preventDefault={() => handleAddProject()}>Add</button onclick={(e) => handleAddProject(e)}>Add</button
> >
<button <button
class="btn btn-danger" class="btn btn-danger"
type="button" type="button"
id="remove-project-button" id="remove-project-button"
on:click|preventDefault={() => handleRemoveProject()}>Remove</button onclick={(e) => handleRemoveProject(e)}>Remove</button
> >
</div> </div>
<p> <p>

View File

@ -10,17 +10,19 @@
<script> <script>
import { Card, CardTitle, CardBody } from "@sveltestrap/sveltestrap"; import { Card, CardTitle, CardBody } from "@sveltestrap/sveltestrap";
import { createEventDispatcher } from "svelte";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
const dispatch = createEventDispatcher(); /* SVelte 5 Props */
let {roles, reloadUser } = $props();
let message = { msg: "", color: "#d63384" }; /* State Init */
let displayMessage = false; let message = $state({ msg: "", color: "#d63384" });
let displayMessage = $state(false);
export let roles; /* Functions */
async function handleAddRole(event) {
event.preventDefault();
async function handleAddRole() {
const username = document.querySelector("#role-username").value; const username = document.querySelector("#role-username").value;
const role = document.querySelector("#role-select").value; const role = document.querySelector("#role-select").value;
@ -41,7 +43,7 @@
if (res.ok) { if (res.ok) {
let text = await res.text(); let text = await res.text();
popMessage(text, "#048109"); popMessage(text, "#048109");
reloadUserList(); reloadUser();
} else { } else {
let text = await res.text(); let text = await res.text();
throw new Error("Response Code " + res.status + "-> " + text); throw new Error("Response Code " + res.status + "-> " + text);
@ -51,7 +53,9 @@
} }
} }
async function handleRemoveRole() { async function handleRemoveRole(event) {
event.preventDefault();
const username = document.querySelector("#role-username").value; const username = document.querySelector("#role-username").value;
const role = document.querySelector("#role-select").value; const role = document.querySelector("#role-select").value;
@ -72,7 +76,7 @@
if (res.ok) { if (res.ok) {
let text = await res.text(); let text = await res.text();
popMessage(text, "#048109"); popMessage(text, "#048109");
reloadUserList(); reloadUser();
} else { } else {
let text = await res.text(); let text = await res.text();
throw new Error("Response Code " + res.status + "-> " + text); throw new Error("Response Code " + res.status + "-> " + text);
@ -89,10 +93,6 @@
displayMessage = false; displayMessage = false;
}, 3500); }, 3500);
} }
function reloadUserList() {
dispatch("reload");
}
</script> </script>
<Card> <Card>
@ -113,19 +113,17 @@
> >
{/each} {/each}
</select> </select>
<!-- PreventDefault on Sveltestrap-Button more complex to achieve than just use good ol' html button -->
<!-- see: https://stackoverflow.com/questions/69630422/svelte-how-to-use-event-modifiers-in-my-own-components -->
<button <button
class="btn btn-primary" class="btn btn-primary"
type="button" type="button"
id="add-role-button" id="add-role-button"
on:click|preventDefault={() => handleAddRole()}>Add</button onclick={(e) => handleAddRole(e)}>Add</button
> >
<button <button
class="btn btn-danger" class="btn btn-danger"
type="button" type="button"
id="remove-role-button" id="remove-role-button"
on:click|preventDefault={() =>handleRemoveRole()}>Remove</button onclick={(e) =>handleRemoveRole(e)}>Remove</button
> >
</div> </div>
<p> <p>

View File

@ -6,14 +6,18 @@
import { Col, Card, CardTitle, CardBody } from "@sveltestrap/sveltestrap"; import { Col, Card, CardTitle, CardBody } from "@sveltestrap/sveltestrap";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
export let ncontent; /* Svelte 5 Props */
let { ncontent } = $props();
let message = { msg: "", color: "#d63384" }; /* State Init */
let displayMessage = false; let message = $state({ msg: "", color: "#d63384" });
let displayMessage = $state(false);
/* Functions */
async function handleEditNotice(event) {
event.preventDefault();
async function handleEditNotice() {
const content = document.querySelector("#notice-content").value; const content = document.querySelector("#notice-content").value;
let formData = new FormData(); let formData = new FormData();
formData.append("new-content", content); formData.append("new-content", content);
@ -56,14 +60,11 @@
value={ncontent} value={ncontent}
id="notice-content" id="notice-content"
/> />
<!-- PreventDefault on Sveltestrap-Button more complex to achieve than just use good ol' html button -->
<!-- see: https://stackoverflow.com/questions/69630422/svelte-how-to-use-event-modifiers-in-my-own-components -->
<button <button
class="btn btn-primary" class="btn btn-primary"
type="button" type="button"
id="edit-notice-button" id="edit-notice-button"
on:click|preventDefault={() => handleEditNotice()}>Edit Notice</button onclick={(e) => handleEditNotice(e)}>Edit Notice</button
> >
</div> </div>
<p> <p>

View File

@ -6,10 +6,13 @@
import { getContext, onMount } from "svelte"; import { getContext, onMount } from "svelte";
import { Col, Card, CardBody, CardTitle } from "@sveltestrap/sveltestrap"; import { Col, Card, CardBody, CardTitle } from "@sveltestrap/sveltestrap";
let scrambled; /*Const Init */
const resampleConfig = getContext("resampling"); const resampleConfig = getContext("resampling");
/* State Init */
let scrambled = $state(false);
/* on Mount */
onMount(() => { onMount(() => {
scrambled = window.localStorage.getItem("cc-scramble-names") != null; scrambled = window.localStorage.getItem("cc-scramble-names") != null;
}); });
@ -33,7 +36,7 @@
type="checkbox" type="checkbox"
id="scramble-names-checkbox" id="scramble-names-checkbox"
style="margin-right: 1em;" style="margin-right: 1em;"
on:click={() => handleScramble()} onclick={() => handleScramble()}
bind:checked={scrambled} bind:checked={scrambled}
/> />
Active? Active?

View File

@ -16,23 +16,19 @@
CardTitle, CardTitle,
CardBody, CardBody,
} from "@sveltestrap/sveltestrap"; } from "@sveltestrap/sveltestrap";
import { createEventDispatcher } from "svelte";
import ShowUsersRow from "./ShowUsersRow.svelte"; import ShowUsersRow from "./ShowUsersRow.svelte";
export let users = []; /*Svelte 5 Props */
let { users = $bindable([]), reloadUser } = $props();
const dispatch = createEventDispatcher();
function reloadUserList() {
dispatch("reload");
}
/* Functions */
function deleteUser(username) { function deleteUser(username) {
if (confirm("Are you sure?")) { if (confirm("Are you sure?")) {
let formData = new FormData(); let formData = new FormData();
formData.append("username", username); formData.append("username", username);
fetch("/config/users/", { method: "DELETE", body: formData }).then((res) => { fetch("/config/users/", { method: "DELETE", body: formData }).then((res) => {
if (res.status == 200) { if (res.status == 200) {
reloadUserList(); reloadUser();
} else { } else {
confirm(res.statusText); confirm(res.statusText);
} }
@ -40,7 +36,6 @@
} }
} }
$: userList = users;
</script> </script>
<Card class="h-100"> <Card class="h-100">
@ -53,7 +48,7 @@
<Button <Button
color="secondary" color="secondary"
size="sm" size="sm"
on:click={() => reloadUserList()} onclick={() => reloadUser()}
style="float: right;">Reload</Button style="float: right;">Reload</Button
> >
</p> </p>
@ -71,13 +66,13 @@
</tr> </tr>
</thead> </thead>
<tbody id="users-list"> <tbody id="users-list">
{#each userList as user} {#each users as user}
<tr id="user-{user.username}"> <tr id="user-{user.username}">
<ShowUsersRow {user} /> <ShowUsersRow {user} />
<td <td
><button ><button
class="btn btn-danger del-user" class="btn btn-danger del-user"
on:click={() => deleteUser(user.username)}>Delete</button onclick={() => deleteUser(user.username)}>Delete</button
></td ></td
> >
</tr> </tr>

View File

@ -10,9 +10,13 @@
import { Button } from "@sveltestrap/sveltestrap"; import { Button } from "@sveltestrap/sveltestrap";
import { fetchJwt } from "../../generic/utils.js" import { fetchJwt } from "../../generic/utils.js"
export let user; /* Svelte 5 Props */
let { user } = $props();
let jwt = ""; /* State Init */
let jwt = $state("");
/* Functions */
function getUserJwt(username) { function getUserJwt(username) {
const p = fetchJwt(username); const p = fetchJwt(username);
p.then((content) => { p.then((content) => {
@ -30,7 +34,7 @@
<td><code>{user?.roles ? user.roles.join(", ") : "No Roles"}</code></td> <td><code>{user?.roles ? user.roles.join(", ") : "No Roles"}</code></td>
<td> <td>
{#if !jwt} {#if !jwt}
<Button color="success" on:click={() => getUserJwt(user.username)} <Button color="success" onclick={() => getUserJwt(user.username)}
>Gen. JWT</Button >Gen. JWT</Button
> >
{:else} {:else}

View File

@ -6,12 +6,17 @@
import { Row, Col, Card, CardTitle, CardBody, Button} from "@sveltestrap/sveltestrap"; import { Row, Col, Card, CardTitle, CardBody, Button} from "@sveltestrap/sveltestrap";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
export let config; /* Svelte 5 Props */
let { config } = $props();
let message; /* State Init */
let displayMessage; let message = $state("");
let displayMessage = $state(false);
/* Functions */
async function handleSettingSubmit(event, selector, target) {
event.preventDefault()
async function handleSettingSubmit(selector, target) {
let form = document.querySelector(selector); let form = document.querySelector(selector);
let formData = new FormData(form); let formData = new FormData(form);
try { try {
@ -58,7 +63,7 @@
id="node-paging-form" id="node-paging-form"
method="post" method="post"
action="/frontend/configuration/" action="/frontend/configuration/"
on:submit|preventDefault={() => handleSettingSubmit("#node-paging-form", "npag")}> onsubmit={(e) => handleSettingSubmit(e, "#node-paging-form", "npag")}>
<input type="hidden" name="key" value="node_list_usePaging" /> <input type="hidden" name="key" value="node_list_usePaging" />
<div class="mb-3"> <div class="mb-3">
<div> <div>

View File

@ -19,21 +19,20 @@
CardTitle, CardTitle,
} from "@sveltestrap/sveltestrap"; } from "@sveltestrap/sveltestrap";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
import { createEventDispatcher } from 'svelte';
export let config; /* Svelte 5 Props */
export let message; let {
export let displayMessage; config,
export let cbmode = false; message = $bindable(),
displayMessage = $bindable(),
cbmode = $bindable(false),
updateSetting
} = $props();
const dispatch = createEventDispatcher(); /* State Init */
function updateSetting(selector, target) { let activeRow = $state(JSON.stringify(config?.plot_general_colorscheme));
dispatch('update-config', {
selector: selector,
target: target
});
}
/* Const Init */
const colorschemes = { const colorschemes = {
Default: [ Default: [
"#00bfff", "#00bfff",
@ -321,7 +320,6 @@
"rgb(189,189,189)", "rgb(189,189,189)",
] ]
} }
</script> </script>
<Row cols={1} class="p-2 g-2"> <Row cols={1} class="p-2 g-2">
@ -350,37 +348,34 @@
<input type="hidden" name="key" value="plot_general_colorscheme" /> <input type="hidden" name="key" value="plot_general_colorscheme" />
<Table hover> <Table hover>
<tbody> <tbody>
{#each Object.entries(cbmode ? cvdschemes : colorschemes) as [name, rgbrow]} {#key activeRow}
<tr> {#each Object.entries(cbmode ? cvdschemes : colorschemes) as [name, rgbrow]}
<th scope="col">{name}</th> <tr>
<td> <th scope="col">{name}</th>
{#if rgbrow.join(",") == config.plot_general_colorscheme} <td>
<input <input
type="radio" type="radio"
name="value" name="value"
value={JSON.stringify(rgbrow)} value={JSON.stringify(rgbrow)}
checked checked={activeRow == JSON.stringify(rgbrow)}
on:click={() => onclick={(e) => {
updateSetting("#colorscheme-form", "cs")} activeRow = JSON.stringify(rgbrow)
updateSetting(e, {
selector: "#colorscheme-form",
target: "cs",
});
}}
/> />
{:else} </td>
<input <td>
type="radio" {#each rgbrow as rgb}
name="value" <span class="color-dot" style="background-color: {rgb};"
value={JSON.stringify(rgbrow)} ></span>
on:click={() => {/each}
updateSetting("#colorscheme-form", "cs")} </td>
/> </tr>
{/if} {/each}
</td> {/key}
<td>
{#each rgbrow as rgb}
<span class="color-dot" style="background-color: {rgb};"
></span>
{/each}
</td>
</tr>
{/each}
</tbody> </tbody>
</Table> </Table>
</form> </form>

View File

@ -19,33 +19,29 @@
CardTitle, CardTitle,
} from "@sveltestrap/sveltestrap"; } from "@sveltestrap/sveltestrap";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
import { createEventDispatcher } from 'svelte';
export let config; /* Svelte 5 Props */
export let message; let {
export let displayMessage; config,
message = $bindable(),
const dispatch = createEventDispatcher(); displayMessage = $bindable(),
function updateSetting(selector, target) { updateSetting
dispatch('update-config', { } = $props();
selector: selector,
target: target
});
}
</script> </script>
<Row cols={3} class="p-2 g-2"> <Row cols={3} class="p-2 g-2">
<!-- LINE WIDTH --> <!-- LINE WIDTH -->
<Col <Col
><Card class="h-100"> ><Card class="h-100">
<!-- Important: Function with arguments needs to be event-triggered like on:submit={() => functionName('Some','Args')} OR no arguments and like this: on:submit={functionName} -->
<form <form
id="line-width-form" id="line-width-form"
method="post" method="post"
action="/frontend/configuration/" action="/frontend/configuration/"
class="card-body" class="card-body"
on:submit|preventDefault={() => onsubmit={(e) => updateSetting(e, {
updateSetting("#line-width-form", "lw")} selector: "#line-width-form",
target: "lw",
})}
> >
<!-- Svelte 'class' directive only on DOMs directly, normal 'class="xxx"' does not work, so style-array it is. --> <!-- Svelte 'class' directive only on DOMs directly, normal 'class="xxx"' does not work, so style-array it is. -->
<CardTitle <CardTitle
@ -90,8 +86,10 @@
method="post" method="post"
action="/frontend/configuration/" action="/frontend/configuration/"
class="card-body" class="card-body"
on:submit|preventDefault={() => onsubmit={(e) => updateSetting(e, {
updateSetting("#plots-per-row-form", "ppr")} selector: "#plots-per-row-form",
target: "ppr",
})}
> >
<!-- Svelte 'class' directive only on DOMs directly, normal 'class="xxx"' does not work, so style-array it is. --> <!-- Svelte 'class' directive only on DOMs directly, normal 'class="xxx"' does not work, so style-array it is. -->
<CardTitle <CardTitle
@ -136,8 +134,10 @@
method="post" method="post"
action="/frontend/configuration/" action="/frontend/configuration/"
class="card-body" class="card-body"
on:submit|preventDefault={() => onsubmit={(e) => updateSetting(e, {
updateSetting("#backgrounds-form", "bg")} selector: "#backgrounds-form",
target: "bg",
})}
> >
<!-- Svelte 'class' directive only on DOMs directly, normal 'class="xxx"' does not work, so style-array it is. --> <!-- Svelte 'class' directive only on DOMs directly, normal 'class="xxx"' does not work, so style-array it is. -->
<CardTitle <CardTitle
@ -180,8 +180,10 @@
method="post" method="post"
action="/frontend/configuration/" action="/frontend/configuration/"
class="card-body" class="card-body"
on:submit|preventDefault={() => onsubmit={(e) => updateSetting(e, {
updateSetting("#colorblindmode-form", "cbm")} selector: "#colorblindmode-form",
target: "cbm",
})}
> >
<!-- Svelte 'class' directive only on DOMs directly, normal 'class="xxx"' does not work, so style-array it is. --> <!-- Svelte 'class' directive only on DOMs directly, normal 'class="xxx"' does not work, so style-array it is. -->
<CardTitle <CardTitle

View File

@ -22,16 +22,23 @@
CardBody CardBody
} from "@sveltestrap/sveltestrap"; } from "@sveltestrap/sveltestrap";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
import { createEventDispatcher } from 'svelte';
import { fetchJwt } from "../../generic/utils.js"; import { fetchJwt } from "../../generic/utils.js";
export let config; /* Svelte 5 Props */
export let message; let {
export let displayMessage; config,
export let username; message = $bindable(),
export let isApi; displayMessage = $bindable(),
username,
isApi,
updateSetting
} = $props();
let jwt = ""; /* State Init */
let jwt = $state("");
let displayCheck = $state(false);
/* Functions */
function getUserJwt(username) { function getUserJwt(username) {
if (username) { if (username) {
const p = fetchJwt(username); const p = fetchJwt(username);
@ -43,7 +50,6 @@
} }
} }
let displayCheck = false;
function clipJwt() { function clipJwt() {
displayCheck = true; displayCheck = true;
// Navigator clipboard api needs a secure context (https) // Navigator clipboard api needs a secure context (https)
@ -71,14 +77,6 @@
displayCheck = false; displayCheck = false;
}, 1000); }, 1000);
} }
const dispatch = createEventDispatcher();
function updateSetting(selector, target) {
dispatch('update-config', {
selector: selector,
target: target
});
}
</script> </script>
<Row cols={isApi ? 3 : 1} class="p-2 g-2"> <Row cols={isApi ? 3 : 1} class="p-2 g-2">
@ -90,8 +88,10 @@
method="post" method="post"
action="/frontend/configuration/" action="/frontend/configuration/"
class="card-body" class="card-body"
on:submit|preventDefault={() => onsubmit={(e) => updateSetting(e, {
updateSetting("#paging-form", "pag")} selector: "#paging-form",
target: "pag",
})}
> >
<!-- Svelte 'class' directive only on DOMs directly, normal 'class="xxx"' does not work, so style-array it is. --> <!-- Svelte 'class' directive only on DOMs directly, normal 'class="xxx"' does not work, so style-array it is. -->
<CardTitle <CardTitle
@ -137,7 +137,7 @@
<CardBody> <CardBody>
<CardTitle>Generate JWT</CardTitle> <CardTitle>Generate JWT</CardTitle>
{#if jwt} {#if jwt}
<Button color="secondary" on:click={() => clipJwt()}> <Button color="secondary" onclick={() => clipJwt()}>
Copy JWT to Clipboard Copy JWT to Clipboard
</Button> </Button>
<p class="mt-2"> <p class="mt-2">
@ -149,7 +149,7 @@
</p> </p>
{/if} {/if}
{:else} {:else}
<Button color="success" on:click={() => getUserJwt(username)}> <Button color="success" onclick={() => getUserJwt(username)}>
Generate JWT for '{username}' Generate JWT for '{username}'
</Button> </Button>
<p class="mt-2"> <p class="mt-2">

View File

@ -19,6 +19,7 @@
* Requirements * Requirements
* - Parent Components must be already Migrated * - Parent Components must be already Migrated
* - TODO: Job.root.svelte, Node.root.svelte * - TODO: Job.root.svelte, Node.root.svelte
* - DONE: Analysis, Status, User
* *
* How-To * How-To
* - Define "Plot-Slotcode" as SV5 Snippet with argument "item" in parent (!) * - Define "Plot-Slotcode" as SV5 Snippet with argument "item" in parent (!)