Collapsible query settings and better mobile support.
Also use a larger list of test clusters, for testing.
This commit is contained in:
parent
4e75739b1d
commit
81e18d4e60
59
src/app.css
59
src/app.css
|
@ -38,6 +38,11 @@ select, input {
|
||||||
padding: 0.3em;
|
padding: 0.3em;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
max-width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
height: calc(100% - 4em);
|
||||||
}
|
}
|
||||||
|
|
||||||
select option {
|
select option {
|
||||||
|
@ -230,13 +235,12 @@ button {
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-color: #95c1d3;
|
border-color: #95c1d3;
|
||||||
flex-grow: 2;
|
flex-grow: 1;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
background-color: #e2eaff;
|
background-color: #e2eaff;
|
||||||
height: 84vh;
|
|
||||||
max-width: 65vw;
|
|
||||||
min-width: 65vw;
|
min-width: 65vw;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-option {
|
.settings-option {
|
||||||
|
@ -254,8 +258,57 @@ button:focus:not(:focus-visible) {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.query-settings-hider {
|
||||||
|
color: rgba(0,0,0, 0.5)
|
||||||
|
}
|
||||||
|
.query-settings-shower {
|
||||||
|
color: rgba(0,0,0, 0.5)
|
||||||
|
}
|
||||||
|
|
||||||
|
.query-settings-hider:before {
|
||||||
|
content: "«";
|
||||||
|
}
|
||||||
|
.query-settings-shower:before {
|
||||||
|
content: "»";
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex: 1;
|
||||||
|
justify-content: space-between;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.query-settings {
|
||||||
|
margin-right: 1rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 720px) {
|
@media (min-width: 720px) {
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 2.4rem;
|
font-size: 2.4rem;
|
||||||
}
|
}
|
||||||
|
.query-settings {
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 719px) {
|
||||||
|
section {
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
.query-settings {
|
||||||
|
flex-grow: 1;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
.query-settings-hider:before {
|
||||||
|
content: '▲';
|
||||||
|
}
|
||||||
|
.query-settings-shower:before {
|
||||||
|
content: '▼';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
} from './+page.js';
|
} from './+page.js';
|
||||||
export let errors, data
|
export let errors, data
|
||||||
|
|
||||||
|
let showQuerySettings = true
|
||||||
let showQueryModal = false
|
let showQueryModal = false
|
||||||
let queryRunning = ''
|
let queryRunning = ''
|
||||||
|
|
||||||
|
@ -90,120 +91,99 @@
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div class="query-settings">
|
{#if showQuerySettings}
|
||||||
<!--
|
<div class="query-settings">
|
||||||
<Header />
|
<!--
|
||||||
<NavBar />
|
<Header />
|
||||||
-->
|
<NavBar />
|
||||||
<h1>Topic Search</h1>
|
-->
|
||||||
<div class="state-error">
|
<h1>Topic Search</h1>
|
||||||
{#if $state.error}
|
<div class="state-error">
|
||||||
<span transition:fade={{duration: 100}}>{$state.error}</span>
|
{#if $state.error}
|
||||||
{#if $state.errorDetails}
|
<span transition:fade={{duration: 100}}>{$state.error}</span>
|
||||||
<div class="state-error-details">{$state.errorDetails}</div>
|
{#if $state.errorDetails}
|
||||||
|
<div class="state-error-details">{$state.errorDetails}</div>
|
||||||
|
{/if}
|
||||||
|
{:else}
|
||||||
|
|
||||||
{/if}
|
{/if}
|
||||||
{:else}
|
</div>
|
||||||
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="settings-option">
|
<div class="settings-option">
|
||||||
<h3>Cluster</h3>
|
<h3>Cluster</h3>
|
||||||
<select disabled={clusterNames.length === 0} bind:value={querySettings.cluster} name="cluster" id="cluster" on:change={updateTopics}>
|
<select disabled={clusterNames.length === 0} bind:value={querySettings.cluster} name="cluster" id="cluster" on:change={updateTopics}>
|
||||||
{#each clusterNames as clusterName}
|
{#each clusterNames as clusterName}
|
||||||
<option value={clusterName}>{clusterName}</option>
|
<option value={clusterName}>{clusterName}</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-option">
|
<div class="settings-option">
|
||||||
<h3>Topic</h3>
|
<h3>Topic</h3>
|
||||||
<select disabled={topics.length === 0} bind:value={querySettings.topic} name="topic" id="topic">
|
<select disabled={topics.length === 0} bind:value={querySettings.topic} name="topic" id="topic">
|
||||||
{#each topics as topic}
|
{#each topics as topic}
|
||||||
<option value={topic}>{topic}</option>
|
<option value={topic}>{topic}</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-option">
|
<div class="settings-option">
|
||||||
<label>
|
<label>
|
||||||
Maximum Results
|
Maximum Results
|
||||||
<input type=number bind:value={querySettings.maxItems} min=0 max=10000>
|
<input type=number bind:value={querySettings.maxItems} min=0 max=10000>
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
<div class="settings-option">
|
|
||||||
<QueryInput
|
|
||||||
bind:jsFilter={querySettings.jsFilter}
|
|
||||||
bind:mutableObjects={querySettings.mutableObjects}
|
|
||||||
bind:queryCode={querySettings.queryCode} />
|
|
||||||
{#if querySettings.jsFilter}
|
|
||||||
<button class="query-input-button" on:click={() => showQueryModal = true}>Open Editor Window</button>
|
|
||||||
{/if}
|
|
||||||
{#if showQueryModal}
|
|
||||||
<Modal onClickOut={() => showQueryModal = false}
|
|
||||||
onCancel={null}
|
|
||||||
onConfirm={() => showQueryModal = false}
|
|
||||||
confirm="Close"
|
|
||||||
title={'JS Filter'}>
|
|
||||||
<QueryInput big
|
|
||||||
bind:jsFilter={querySettings.jsFilter}
|
|
||||||
bind:mutableObjects={querySettings.mutableObjects}
|
|
||||||
bind:queryCode={querySettings.queryCode} />
|
|
||||||
</Modal>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Previous 'Start' style
|
|
||||||
<div class="settings-option query-type">
|
|
||||||
<span>Query Type:</span>
|
|
||||||
<span>
|
|
||||||
<label title="Consume and display new events as they are produced.">
|
|
||||||
<input type=radio bind:group={querySettings.mode} name="mode" value={queryMode.REAL_TIME}>
|
|
||||||
Real Time
|
|
||||||
</label>
|
</label>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
|
||||||
<label title="Query all messages that currently exist, then stop.">
|
<div class="settings-option">
|
||||||
<input type=radio bind:group={querySettings.mode} name="mode" value={queryMode.ONE_SHOT}>
|
<QueryInput
|
||||||
One Shot
|
bind:jsFilter={querySettings.jsFilter}
|
||||||
</label>
|
bind:mutableObjects={querySettings.mutableObjects}
|
||||||
</span>
|
bind:queryCode={querySettings.queryCode} />
|
||||||
</div>
|
{#if querySettings.jsFilter}
|
||||||
|
<button class="query-input-button" on:click={() => showQueryModal = true}>Open Editor Window</button>
|
||||||
|
{/if}
|
||||||
|
{#if showQueryModal}
|
||||||
|
<Modal onClickOut={() => showQueryModal = false}
|
||||||
|
onCancel={null}
|
||||||
|
onConfirm={() => showQueryModal = false}
|
||||||
|
confirm="Close"
|
||||||
|
title={'JS Filter'}>
|
||||||
|
<QueryInput big
|
||||||
|
bind:jsFilter={querySettings.jsFilter}
|
||||||
|
bind:mutableObjects={querySettings.mutableObjects}
|
||||||
|
bind:queryCode={querySettings.queryCode} />
|
||||||
|
</Modal>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="query-button">
|
<div class="query-button">
|
||||||
{#if queryRunning}
|
{#if queryRunning && $state.queryState !== queryState.DONE}
|
||||||
<button class="danger" on:click={() => queryRunning = stopQuery(querySettings)}>Stop Query</button>
|
<div transition:slide|local class="stop-button">
|
||||||
{:else}
|
<button class="danger" on:click={() => queryRunning = stopQuery(querySettings)}>
|
||||||
<button class="colored" on:click={() => queryRunning = startQuery(querySettings)}>Start Query</button>
|
{queryRunning === queryMode.REAL_TIME ? 'End Real Time' : 'Cancel One-Shot'} Query
|
||||||
{/if}
|
</button>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div transition:slide|local class="start-buttons colored">
|
||||||
|
<button class="colored" on:click={() => queryRunning = startQuery({...querySettings, mode: queryMode.ONE_SHOT})}>
|
||||||
|
Start One-Shot
|
||||||
|
</button>
|
||||||
|
<div class="separator"></div>
|
||||||
|
<button class="colored" on:click={() => queryRunning = startQuery({...querySettings, mode: queryMode.REAL_TIME})}>
|
||||||
|
Start Real-Time
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
-->
|
{/if}
|
||||||
|
|
||||||
<div class="query-button">
|
|
||||||
{#if queryRunning && $state.queryState !== queryState.DONE}
|
|
||||||
<div transition:slide|local class="stop-button">
|
|
||||||
<button class="danger" on:click={() => queryRunning = stopQuery(querySettings)}>
|
|
||||||
{queryRunning === queryMode.REAL_TIME ? 'End Real Time' : 'Cancel One-Shot'} Query
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<div transition:slide|local class="start-buttons colored">
|
|
||||||
<button class="colored" on:click={() => queryRunning = startQuery({...querySettings, mode: queryMode.ONE_SHOT})}>
|
|
||||||
Start One-Shot
|
|
||||||
</button>
|
|
||||||
<div class="separator"></div>
|
|
||||||
<button class="colored" on:click={() => queryRunning = startQuery({...querySettings, mode: queryMode.REAL_TIME})}>
|
|
||||||
Start Real-Time
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="data-view-container">
|
<div class="data-view-container">
|
||||||
<div class="data-view-bar">
|
<div class="data-view-bar">
|
||||||
<div class="border-between">
|
<div class="border-between">
|
||||||
|
<button class={showQuerySettings ? "query-settings-hider" : "query-settings-shower"}
|
||||||
|
on:click={() => showQuerySettings = !showQuerySettings}></button>
|
||||||
<button class={jsonDisplay.expandAll ? 'selected' : ''}
|
<button class={jsonDisplay.expandAll ? 'selected' : ''}
|
||||||
on:click={() => jsonDisplay.expandAll = !jsonDisplay.expandAll}>
|
on:click={() => jsonDisplay.expandAll = !jsonDisplay.expandAll}>
|
||||||
Expand All Objects
|
Expand All Objects
|
||||||
|
@ -252,6 +232,7 @@
|
||||||
.data-view-container {
|
.data-view-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
.data-view-bar {
|
.data-view-bar {
|
||||||
background-color: #d7dbf3;
|
background-color: #d7dbf3;
|
||||||
|
@ -299,14 +280,6 @@
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
section {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex: 1;
|
|
||||||
justify-content: space-between;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -321,16 +294,6 @@
|
||||||
background-color: #575757;
|
background-color: #575757;
|
||||||
}
|
}
|
||||||
|
|
||||||
.query-settings {
|
|
||||||
margin-right: 1rem;
|
|
||||||
flex-grow: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: auto;
|
|
||||||
padding: 1em;
|
|
||||||
height: 84.5vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.query-type {
|
.query-type {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
|
@ -159,6 +159,9 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.data-view {
|
||||||
|
min-height: 40%;
|
||||||
|
}
|
||||||
.cluster-listing {
|
.cluster-listing {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -183,13 +186,6 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
section {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex: 1;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -210,14 +206,6 @@
|
||||||
min-width: 20vw;
|
min-width: 20vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.query-settings {
|
|
||||||
margin-right: 1rem;
|
|
||||||
padding: 1em;
|
|
||||||
overflow: auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-sub-option {
|
.settings-sub-option {
|
||||||
margin-top: 0.2em;
|
margin-top: 0.2em;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
30
src/utils.js
30
src/utils.js
|
@ -29,18 +29,28 @@ const jsonRequest = type => async (path, object) => fetch(backendUrl + path, {
|
||||||
export const postJson = (path, object) => jsonRequest('POST')(path, object)
|
export const postJson = (path, object) => jsonRequest('POST')(path, object)
|
||||||
export const putJson = (path, object) => jsonRequest('PUT')(path, object)
|
export const putJson = (path, object) => jsonRequest('PUT')(path, object)
|
||||||
|
|
||||||
|
const mockCluster = {
|
||||||
|
clientId: 'TestClient',
|
||||||
|
brokers: ['testbroker.com:5000'],
|
||||||
|
ssl: true,
|
||||||
|
sasl: {
|
||||||
|
mechanism: 'SCRAM-SHA-512',
|
||||||
|
username: 'testuser',
|
||||||
|
password: 'XXXXXXXXXXXXXXXXXXXXXX'
|
||||||
|
}
|
||||||
|
}
|
||||||
const mockApi = {
|
const mockApi = {
|
||||||
'/clusters': {
|
'/clusters': {
|
||||||
'TestCluster': {
|
'TestCluster1': mockCluster,
|
||||||
clientId: 'TestClient',
|
'TestCluster2': mockCluster,
|
||||||
brokers: ['testbroker.com:5000'],
|
'TestCluster3': mockCluster,
|
||||||
ssl: true,
|
'TestCluster4': mockCluster,
|
||||||
sasl: {
|
'TestCluster5': mockCluster,
|
||||||
mechanism: 'SCRAM-SHA-512',
|
'TestCluster6': mockCluster,
|
||||||
username: 'testuser',
|
'TestCluster7': mockCluster,
|
||||||
password: 'XXXXXXXXXXXXXXXXXXXXXX'
|
'TestCluster8': mockCluster,
|
||||||
}
|
'TestCluster9': mockCluster,
|
||||||
}
|
'TestCluster10': mockCluster,
|
||||||
},
|
},
|
||||||
'/topics/TestCluster': ['NewReleases']
|
'/topics/TestCluster': ['NewReleases']
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue