diff --git a/src/app.css b/src/app.css
index 548ba84..e0c17f0 100644
--- a/src/app.css
+++ b/src/app.css
@@ -1,7 +1,8 @@
@import '@fontsource/fira-mono';
+@import url('https://fonts.googleapis.com/css2?family=Fira+Sans&family=Montserrat:wght@500&display=swap');
:root {
- font-family: Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
+ font-family: 'Fira Sans', Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
--font-mono: 'Fira Mono', monospace;
--pure-white: #ffffff;
@@ -9,13 +10,31 @@
--secondary-color: #d0dde9;
--tertiary-color: #edf0f8;
--accent-color: #ff0df8;
- --heading-color: rgba(0, 0, 0, 0.7);
+ --heading-color: rgba(0, 0, 0, 0.8);
--text-color: #444444;
--background-without-opacity: rgba(255, 255, 255, 0.7);
--column-width: 42rem;
--column-margin-top: 4rem;
}
+select, button {
+ font-family: 'Fira Sans', Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+ font-size: 90%;
+ border-style: solid;
+ border-radius: 0;
+ border-width: 1px;
+ border-color: #888888;
+ padding: 0.2em;
+}
+
+button {
+ padding: 0.2em 0.8em;
+}
+
+nav {
+ font-family: 'Liberation Sans', sans-serif;
+}
+
body {
min-height: 100vh;
margin: 0;
@@ -54,14 +73,21 @@ body::before {
flex-direction: column;
}
+h1 {
+ font-weight: bold;
+ color: #111111;
+}
+
h1,
h2,
p {
+ font-family: 'Montserrat', sans-serif;
font-weight: 400;
color: var(--heading-color);
}
h3 {
+ font-family: 'Montserrat', sans-serif;
margin-top: 0;
}
@@ -108,6 +134,20 @@ button {
font-family: inherit;
}
+.data-view {
+ display: flex;
+ flex-direction: column;
+ border-style: solid;
+ border-width: 1px;
+ border-color: #95c1d3;
+ flex-grow: 2;
+ padding: 1em;
+ background-color: #e2eaff;
+ height: 86vh;
+ max-width: 70vw;
+ overflow-y: scroll;
+}
+
.settings-option {
padding: 1em;
margin-bottom: 1em;
diff --git a/src/lib/constants.js b/src/lib/constants.js
index d65dea2..55854c7 100644
--- a/src/lib/constants.js
+++ b/src/lib/constants.js
@@ -1,4 +1,8 @@
export const queryMode = {
REAL_TIME: 'realTime',
ONE_SHOT: 'oneShot'
-}
\ No newline at end of file
+}
+
+export const backendAddressAndPort = 'localhost:3000'
+
+export const backendUrl = `http://${backendAddressAndPort}`
\ No newline at end of file
diff --git a/src/lib/header/NavBar.svelte b/src/lib/header/NavBar.svelte
index ee2c982..6f9f4d1 100644
--- a/src/lib/header/NavBar.svelte
+++ b/src/lib/header/NavBar.svelte
@@ -8,7 +8,7 @@
-
- Home
+ Message Search
-
Settings
diff --git a/src/lib/state.js b/src/lib/state.js
index 1ea5f1b..676a4ae 100644
--- a/src/lib/state.js
+++ b/src/lib/state.js
@@ -1,7 +1,7 @@
// noinspection JSCheckFunctionSignatures
import { writable } from 'svelte/store'
-import {queryMode} from "./constants.js";
+import { backendAddressAndPort, queryMode } from "./constants.js";
const mockItems = [
{
@@ -19,9 +19,9 @@ const mockItems = [
"broughtToYouBy": "20th Century Fox",
"title": "Star Wars 2"
},
-].map(o => ({value: o, timestamp: new Date().getTime()}))
+].map(o => ({ value: o, timestamp: new Date().getTime() }))
-const testMode = true
+const testMode = false
export const state = writable({
items: [],
itemCount: undefined,
@@ -38,34 +38,39 @@ let disconnected = false
const getRandomFromArray = array => array[Math.floor(Math.random() * array.length)]
+const testQuery = (mode, jsFilter, queryCode) => {
+ try {
+ const f = new Function('message', 'value', queryCode)
+ if (mode === queryMode.REAL_TIME) {
+ const addItem = () => {
+ const item = getRandomFromArray(mockItems)
+ if (!jsFilter || f(item, item.value)) {
+ item.timestamp = new Date().getTime()
+ updateClearError(s => ({ ...s, items: [item, ...s.items].slice(0, itemLimit), itemCount: 0 }))
+ }
+ setTimeout(addItem, 2000)
+ }
+ setTimeout(addItem, 2000)
+ } else {
+ updateClearError(s => ({ ...s, items: mockItems.filter(item => !jsFilter || f(item, item.value)), itemCount: 0 }))
+ }
+ } catch (e) {
+ updateClearError(s => ({ ...s, error: e.toString() }))
+ }
+}
+
+// noinspection JSUnusedGlobalSymbols
export const query = async ({ cluster, topic, mode, jsFilter, queryCode, maxItems, mutableObjects }) => {
- updateClearError(s => ({...s, items: [], itemCount: 0}))
+ updateClearError(s => ({ ...s, items: [], itemCount: 0 }))
+ if (testMode) {
+ testQuery(mode, jsFilter, queryCode)
+ return
+ }
if (disconnected) {
connect()
disconnected = false
}
- if (testMode) {
- try {
- const f = new Function('message', 'value', queryCode)
- if (mode === queryMode.REAL_TIME) {
- const addItem = () => {
- const item = getRandomFromArray(mockItems)
- if (!jsFilter || f(item, item.value)) {
- item.timestamp = new Date().getTime()
- updateClearError(s => ({...s, items: [item, ...s.items].slice(0, itemLimit), itemCount: 0}))
- }
- setTimeout(addItem, 2000)
- }
- setTimeout(addItem, 2000)
- } else {
- updateClearError(s => ({...s, items: mockItems.filter(item => !jsFilter || f(item, item.value)), itemCount: 0}))
- }
- } catch (e) {
- updateClearError(s => ({ ...s, error: e.toString() }))
- }
- } else {
- updateClearError(s => ({ ...s, items: [], itemCount: 0 }))
- }
+ updateClearError(s => ({ ...s, items: [], itemCount: 0 }))
itemLimit = maxItems
ws.send(JSON.stringify({
cluster,
@@ -78,27 +83,26 @@ export const query = async ({ cluster, topic, mode, jsFilter, queryCode, maxItem
}
export const connect = () => {
- ws = new WebSocket(`ws://localhost:3000`)
+ ws = new WebSocket(`ws://${backendAddressAndPort}`)
if (!ws) {
- updateClearError(s => ({...s, error: 'Unable to connect to websocket.'}))
+ updateClearError(s => ({ ...s, error: 'Unable to connect to websocket.' }))
return
}
- ws.addEventListener('close', () => { disconnected = true })
+ ws.addEventListener('close', () => {
+ disconnected = true
+ })
ws.addEventListener('open', () => {
console.log('WebSocket opened')
- // ws.send(JSON.stringify({
- // searchCode: 'return message.value?.UserId === "MINTERCI"'
- // }))
})
ws.addEventListener('message', message => {
- //console.log('WebSocket message received', message)
let data;
try {
data = JSON.parse(message.data)
- switch (data.type) {
+ console.log('WebSocket message received', data)
+ switch (data?.type.toLowerCase()) {
case 'complete':
updateClearError(s => ({
...s,
@@ -114,7 +118,7 @@ export const connect = () => {
case 'message':
updateClearError(s => ({
...s,
- items: [data.message, ...s.items].slice(0, itemLimit)
+ items: console.log('new item', data.message) || [data.message, ...s.items].slice(0, itemLimit)
}))
break;
}
@@ -126,4 +130,4 @@ export const connect = () => {
ws.addEventListener('close', () => {
console.log('WebSocket closed')
})
-}
\ No newline at end of file
+}
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index f4e7802..bbc1a94 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -2,16 +2,16 @@
import { onMount } from 'svelte'
import { JsonView } from '@zerodevx/svelte-json-view'
import { state, connect, query } from '$lib/state';
- import { queryMode } from "../lib/constants.js";
+ import { queryMode, backendUrl } from "../lib/constants.js";
- let expandAll = false
- let showMetadata = false
+ let expandAll = true
+ let showMetadata = true
const querySettings = {
topic: null,
cluster: null,
mode: queryMode.REAL_TIME,
- jsFilter: true,
+ jsFilter: false,
maxItems: 20,
mutableObjects: false,
queryCode:
@@ -21,21 +21,23 @@
return message.value.eventType === "Television";`
}
- const makeRequest = async () => query(querySettings)
-
let topics = []
let clusters = []
const updateTopics = async () => {
topics = []
- const response = await fetch(`http://localhost:3000/topics/${querySettings.cluster}`)
- topics = await response.json()
- topics.sort()
- console.log('topics', topics)
- querySettings.topic = topics[0]
+ try {
+ const response = await fetch(`${backendUrl}/topics/${querySettings.cluster}`)
+ topics = await response.json()
+ topics.sort()
+ console.log('topics', topics)
+ querySettings.topic = topics[0]
+ } catch (e) {
+ console.log('fetch error:', e.toString())
+ }
}
onMount(async () => {
connect();
- const response = await fetch(`http://localhost:3000/clusters`)
+ const response = await fetch(`${backendUrl}/clusters`)
clusters = Object.keys(await response.json())
querySettings.cluster = clusters[0]
await updateTopics()
@@ -86,7 +88,7 @@ return message.value.eventType === "Television";`
-
+
{#if querySettings.jsFilter}
{#if $state.items?.length > 0}
-
-
item.value)}
+
+ item.value)}
depth={expandAll ? Infinity : 1}/>
{:else }
-
+
No query data
{/if}
@@ -144,6 +146,7 @@ return message.value.eventType === "Television";`
flex-direction: row;
flex: 1;
justify-content: space-between;
+ overflow: hidden;
}
h1 {
@@ -171,8 +174,16 @@ return message.value.eventType === "Television";`
flex-grow: 1;
display: flex;
flex-direction: column;
+ overflow: auto;
+ padding: 1em;
+ height: 86vh;
}
+ .query-input-header {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ }
.query-input-display {
margin-top: 1em;
display: flex;
@@ -180,6 +191,7 @@ return message.value.eventType === "Television";`
}
.query-input {
min-height: 4vw;
+ resize: vertical;
}
.query-type {
@@ -220,15 +232,6 @@ return message.value.eventType === "Television";`
}
*/
- .json-view {
- border-radius: 4px;
- flex-grow: 6;
- padding: 1em;
- background-color: #e2eaff;
- height: 86vh;
- overflow-y: scroll;
- }
-
.no-query-data {
display: flex;
align-items: center;
diff --git a/src/routes/settings/+page.svelte b/src/routes/settings/+page.svelte
index 37302ad..3774399 100644
--- a/src/routes/settings/+page.svelte
+++ b/src/routes/settings/+page.svelte
@@ -1,7 +1,8 @@
-
+
@@ -69,22 +98,63 @@
SASL:
-
- Mechanism:
+
-
- Username:
+
-
-
+
+
+
+
+
+ {#each Object.entries(clusters) as [clusterName, cluster]}
+
+
{cluster.clusterName}
+
+
+
+
+
+ {/each}