Fix jsonRequest()

Modal transitions.
Almost got the Footer working (hidden for now)
More flexibility with sasl config.
This commit is contained in:
Sage Vaillancourt 2022-08-23 16:53:03 -04:00
parent 368da3360a
commit 6dcc90f47d
9 changed files with 68 additions and 37 deletions

View File

@ -18,6 +18,12 @@
--column-margin-top: 4rem; --column-margin-top: 4rem;
} }
.root-div {
height: 100vh;
display: flex;
flex-direction: column;
}
select, button { select, button {
font-family: Roboto, Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; font-family: Roboto, Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
font-size: 90%; font-size: 90%;

View File

@ -7,6 +7,6 @@
%sveltekit.head% %sveltekit.head%
</head> </head>
<body> <body>
<div>%sveltekit.body%</div> <div class="root-div">%sveltekit.body%</div>
</body> </body>
</html> </html>

View File

@ -1,4 +1,5 @@
<script> <script>
import { fade, slide } from 'svelte/transition'
export let confirm = 'Confirm' export let confirm = 'Confirm'
export let level = '' export let level = ''
export let title export let title
@ -7,8 +8,8 @@
export let onClickOut = () => {} export let onClickOut = () => {}
</script> </script>
<div class="modal" on:click|self={() => onClickOut && onClickOut()}> <div transition:fade class="modal" on:click|self={() => onClickOut && onClickOut()}>
<div class="modal-content" on:click={() => {}}> <div transition:slide class="modal-content" on:click={() => {}}>
{#if title} {#if title}
<h2 class="modal-title">{title}</h2> <h2 class="modal-title">{title}</h2>
{/if} {/if}

View File

@ -1,3 +1,5 @@
import { npm_package_version } from "$env/static/private";
export const queryMode = { export const queryMode = {
REAL_TIME: 'realTime', REAL_TIME: 'realTime',
ONE_SHOT: 'oneShot' ONE_SHOT: 'oneShot'
@ -7,4 +9,6 @@ export const backendAddressAndPort = 'localhost:3000'
export const backendUrl = `http://${backendAddressAndPort}` export const backendUrl = `http://${backendAddressAndPort}`
export const saslAuthMethods = ['PLAIN', 'SCRAM-SHA-256', 'SCRAM-SHA-512', 'AWS'] export const saslAuthMethods = ['PLAIN', 'SCRAM-SHA-256', 'SCRAM-SHA-512', 'AWS']
export const clientVersion = npm_package_version

View File

@ -34,7 +34,7 @@ const mockItems = [
}, },
].map(addMetadata) ].map(addMetadata)
export const testMode = true export const testMode = false
export const state = writable({ export const state = writable({
items: [], items: [],
@ -145,6 +145,10 @@ export const connect = () => {
}) })
ws.addEventListener('message', message => { ws.addEventListener('message', message => {
if (message.data === 'CONNECTED') {
updateClearError(s => ({...s}))
return
}
let data; let data;
try { try {
data = JSON.parse(message.data) data = JSON.parse(message.data)

View File

@ -1,6 +1,7 @@
<script> <script>
import Header from '$lib/header/Header.svelte'; import Header from '$lib/header/Header.svelte'
import '../app.css'; import '../app.css'
import { clientVersion } from '../lib/constants.js'
</script> </script>
<Header /> <Header />
@ -9,14 +10,16 @@
<slot /> <slot />
</main> </main>
<!--<footer></footer>--> <!--
<footer>Version {clientVersion}</footer>
-->
<style> <style>
main { main {
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 1rem; padding: 1rem 1rem 0;
width: 100%; width: 100%;
/* /*
max-width: 1024px; max-width: 1024px;
@ -26,11 +29,13 @@
} }
footer { footer {
padding: 5px;
font-size: 75%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 40px; opacity: 0.5;
} }
footer a { footer a {
@ -38,8 +43,5 @@
} }
@media (min-width: 480px) { @media (min-width: 480px) {
footer {
padding: 40px 0;
}
} }
</style> </style>

View File

@ -197,7 +197,7 @@ return message.value.eventType === "Television";`
{$state.itemCount} Messages {$state.itemCount} Messages
</div> </div>
{/if} {/if}
<div class="border-between"> <div class="border-between zoom-buttons">
<button on:click={fontDown} style="border-color: #aaa;">-</button> <button on:click={fontDown} style="border-color: #aaa;">-</button>
<button on:click={fontUp}>+</button> <button on:click={fontUp}>+</button>
</div> </div>
@ -220,6 +220,10 @@ return message.value.eventType === "Television";`
.data-view { .data-view {
border-top: none; border-top: none;
} }
.data-view-container {
display: flex;
flex-direction: column;
}
.data-view-bar { .data-view-bar {
background-color: #d7dbf3; background-color: #d7dbf3;
border-style: solid; border-style: solid;
@ -236,10 +240,14 @@ return message.value.eventType === "Television";`
border-width: 1px; border-width: 1px;
border-style: none; border-style: none;
display: flex; display: flex;
flex-grow: 1;
} }
.border-between button:last-child { .border-between button:last-child {
border-right: none; border-right: none;
} }
.zoom-buttons button {
width: 2.5em;
}
.data-view-bar button { .data-view-bar button {
border-color: white; border-color: white;
border-style: none; border-style: none;
@ -291,7 +299,7 @@ return message.value.eventType === "Television";`
flex-direction: column; flex-direction: column;
overflow: auto; overflow: auto;
padding: 1em; padding: 1em;
height: 83vh; height: 84.5vh;
} }
.query-type { .query-type {

View File

@ -4,8 +4,8 @@
import { apiFetch, findLast, deepCopy, postJson, putJson } from "../../utils.js"; import { apiFetch, findLast, deepCopy, postJson, putJson } from "../../utils.js";
import Modal from "../../lib/Modal.svelte"; import Modal from "../../lib/Modal.svelte";
const addCluster = async cluster => fetchClusters(await postJson('/clusters', cluster)) const addCluster = async () => fetchClusters(await postJson('/clusters', getConfig()))
const updateCluster = async cluster => fetchClusters(await putJson('/clusters', cluster)) const updateCluster = async () => fetchClusters(await putJson('/clusters', getConfig()))
const deleteCluster = async clusterName => fetchClusters(await postJson('/clusters/delete', { clusterName })) const deleteCluster = async clusterName => fetchClusters(await postJson('/clusters/delete', { clusterName }))
let clusters = [] let clusters = []
@ -22,6 +22,7 @@
const values = Object.values(clusters) const values = Object.values(clusters)
if (values.length > 0) { if (values.length > 0) {
config = deepCopy(values[0]) config = deepCopy(values[0])
useSasl = !!config.sasl
} }
} }
onMount(async () => { onMount(async () => {
@ -32,11 +33,15 @@
config = emptyConfig() config = emptyConfig()
} }
let useSasl = false
const getConfig = () => ({ ...config, sasl: useSasl ? config.sasl : undefined })
const emptyConfig = () => ({ const emptyConfig = () => ({
originalName: null, // A `null` originalName indicates that the config is new, originalName: null, // A `null` originalName indicates that the config is new,
clusterName: '', // and will be POSTed as a new cluster, not PUTted, updating an existing one clusterName: '', // and will be POSTed as a new cluster, not PUTted, updating an existing one
clientId: '', clientId: '',
brokers: [''], brokers: [''],
useSasl: true,
ssl: true, ssl: true,
sasl: { sasl: {
mechanism: '', mechanism: '',
@ -104,27 +109,29 @@
<!-- TODO: Add options for SSL config --> <!-- TODO: Add options for SSL config -->
<div class="settings-option"> <div class="settings-option">
<div>SASL:</div> <div>SASL: <input type=checkbox bind:checked={useSasl} /></div>
<div class="settings-sub-option"> {#if useSasl}
<div>Auth Mechanism:</div> <div class="settings-sub-option">
<select bind:value={config.sasl.mechanism}> <div>Auth Mechanism:</div>
{#each saslAuthMethods as method} <select bind:value={config.sasl.mechanism}>
<option value={method}>{method}</option> {#each saslAuthMethods as method}
{/each} <option value={method}>{method}</option>
</select> {/each}
</div> </select>
<div class="settings-sub-option"> </div>
<div>Username:</div> <div class="settings-sub-option">
<input bind:value={config.sasl.username}> <div>Username:</div>
</div> <input bind:value={config.sasl.username}>
<div class="settings-sub-option"> </div>
<div>Password:</div> <div class="settings-sub-option">
<input type="password" bind:value={config.sasl.password}> <div>Password:</div>
</div> <input type="password" bind:value={config.sasl.password}>
</div>
{/if}
</div> </div>
<button style="float: right;" <button style="float: right;"
on:click={() => (config.originalName ? updateCluster : addCluster)(config)}>{config.originalName ? 'Update Cluster Config' : 'Add Cluster Config'}</button> on:click={() => (config.originalName ? updateCluster() : addCluster())}>{config.originalName ? 'Update Cluster Config' : 'Add Cluster Config'}</button>
</div> </div>
<div class="data-view"> <div class="data-view">
@ -207,7 +214,6 @@
.query-settings { .query-settings {
margin-right: 1rem; margin-right: 1rem;
padding: 1em; padding: 1em;
height: 83vh;
overflow: auto; overflow: auto;
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -12,7 +12,7 @@ export const findLast = array => {
return array[array.length - 1] return array[array.length - 1]
} }
const jsonRequest = type => async (path, object) => fetch(path, { const jsonRequest = type => async (path, object) => fetch(backendUrl + path, {
method: type, method: type,
body: JSON.stringify(object), body: JSON.stringify(object),
headers: { headers: {