Skip to content

Commit

Permalink
WIP: swap reactive statements for stores
Browse files Browse the repository at this point in the history
  • Loading branch information
UncleGedd committed Nov 1, 2024
1 parent f57b039 commit 795577c
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 75 deletions.
2 changes: 0 additions & 2 deletions ui/src/lib/components/AnsiDisplay/component.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
export const addMessage = (message: string) => {
if (!message || !scrollAnchor?.parentElement) return
console.log('message:', message)
const html = convert.toHtml(message)
const lineElement = document.createElement('div')
lineElement.className = 'log-line text-gray-300 text-sm font-mono py-0.5'
Expand Down
140 changes: 67 additions & 73 deletions ui/src/routes/(resources)/workloads/pods/logs/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

<script lang="ts">
import { onMount } from 'svelte'
import { derived, writable } from 'svelte/store'
import { AnsiDisplay, Dropdown } from '$components'
import { PodTable } from '$features/k8s'
Expand Down Expand Up @@ -34,28 +35,11 @@
}
}
// Search term
let logEventSource: EventSource
let search = ''
// raw data
let namespaces: Set<string> = new Set()
let pods: Pod[] = []
// filtered data for dropdowns
let filteredPods: Pod[] = []
let filteredContainers: Container[] = []
// Selected values
let selectedPod: Pod | null
let selectedPodName: string | null
let selectedNamespace: string | null
let selectedContainerName: string | null
// todo: test back/forward button, etc
let logEventSource: EventSource
// todo: BUG when you change pods it should also update the containers
function cleanupLogs() {
if (logEventSource) {
logEventSource.close()
Expand All @@ -64,45 +48,57 @@
}
}
// update filtered pods for dropdown
$: filteredPods = selectedNamespace ? Array.from(pods).filter((p) => p.metadata.namespace === selectedNamespace) : []
// update filtered containers for dropdown
$: filteredContainers = selectedPod?.spec.containers ?? []
// Handle namespace changes
$: if (selectedNamespace) {
cleanupLogs()
selectedPod = null
selectedPodName = null
selectedContainerName = null
}
// Create base stores
const pods = writable<Pod[]>([])
const namespaces = writable<Set<string>>(new Set())
const namespace = writable<string | null>(null)
const podName = writable<string | null>(null)
const containerName = writable<string | null>(null)
const selectedPod = writable<Pod | null>(null)
// Derive filtered lists
const filteredPods = derived([namespace], () =>
$namespace ? Array.from($pods).filter((p) => p.metadata.namespace === $namespace) : [],
)
const filteredContainers = derived([selectedPod], () => $selectedPod?.spec.containers ?? [])
// Subscribe to changes
namespace.subscribe((newNamespace) => {
if (newNamespace) {
cleanupLogs()
podName.set(null)
selectedPod.set(null)
containerName.set(null)
}
})
// Handle pod selection independently
$: if (selectedPodName) {
console.log('Pod selected:', selectedPodName)
cleanupLogs()
selectedPod = filteredPods.find((p) => p.metadata.name === selectedPodName) ?? null
// selectedContainerName = null
}
podName.subscribe((newPodName) => {
if (newPodName) {
cleanupLogs()
containerName.set(null)
const pod = $filteredPods.find((p) => p.metadata.name === newPodName)
selectedPod.set(pod ?? null)
}
})
// Handle container selection independently
$: if (selectedContainerName) {
console.log('Container selected:', selectedContainerName)
cleanupLogs()
containerName.subscribe((newContainerName) => {
if (newContainerName) {
cleanupLogs()
// Set up new event source
const logsURL = `/api/v1/resources/workloads/pods/logs?namespace=${selectedNamespace}&pod=${selectedPodName}&container=${selectedContainerName}`
logEventSource = new EventSource(logsURL)
// create new SSE stream
const logsURL = `/api/v1/resources/workloads/pods/logs?namespace=${$namespace}&pod=${$podName}&container=${newContainerName}`
logEventSource = new EventSource(logsURL)
logEventSource.onmessage = (event) => {
addMessage(event.data)
}
logEventSource.onmessage = (event) => {
addMessage(event.data)
}
logEventSource.onerror = (event) => {
console.error('EventSource failed:', event)
logEventSource.onerror = (event) => {
console.error('EventSource failed:', event)
}
}
}
})
onMount(() => {
// set up sse stream for pods
Expand All @@ -112,25 +108,23 @@
podEventSource.onmessage = (event) => {
const data = JSON.parse(event.data)
// clear existing data
namespaces.clear()
pods = []
const newNamespaces = new Set<string>()
// Process each item in the data array
data.forEach((p: Pod) => {
namespaces.add(p.metadata.namespace)
pods.push(p)
newNamespaces.add(p.metadata.namespace)
})
// Trigger reactivity by reassigning the sets (todo: kind of weird)
namespaces = new Set(Array.from(namespaces).sort())
pods = pods
// Update stores
pods.set(data)
namespaces.set(new Set(Array.from(newNamespaces).sort()))
// set default values
if (!selectedNamespace) {
selectedNamespace = pods[0].metadata.namespace
}
// Set default namespace if none selected
namespace.subscribe((currentNamespace) => {
if (!currentNamespace && data.length > 0) {
namespace.set(data[0].metadata.namespace)
}
})() // Immediately unsubscribe after first run
}
podEventSource.onerror = (event) => {
Expand All @@ -153,7 +147,7 @@
<div class="flex h-full w-full flex-col bg-gray-800 rounded-lg">
<!-- Header -->
<div class="flex items-center justify-between py-2 border-b border-gray-700 mx-4">
<!-- Left section: Title, search, and log controls -->
<!-- Left section: title, search, and log controls -->
<div class="flex items-center space-x-6">
<!-- Logo and title -->
<div class="flex items-center">
Expand Down Expand Up @@ -203,27 +197,27 @@
<!-- Dropdowns -->
<div class="flex space-x-4 p-4">
<Dropdown
bind:selectedValue={selectedNamespace}
items={Array.from(namespaces)}
bind:selectedValue={$namespace}
items={Array.from($namespaces)}
id="ns-dropdown"
width="w-48"
placeholder="Select namespace"
/>
<Dropdown
bind:selectedValue={selectedPodName}
items={filteredPods.map((p) => p.metadata.name)}
bind:selectedValue={$podName}
items={$filteredPods.map((p) => p.metadata.name)}
id="pod-dropdown"
width="w-48"
placeholder="Select pod"
disabled={!selectedNamespace}
disabled={!$namespace}
/>
<Dropdown
bind:selectedValue={selectedContainerName}
items={filteredContainers.map((c) => c.name)}
bind:selectedValue={$containerName}
items={$filteredContainers.map((c) => c.name)}
id="container-dropdown"
width="w-48"
placeholder="Select container"
disabled={!selectedPodName}
disabled={!$podName}
/>
</div>
<!-- Logs content area -->
Expand Down

0 comments on commit 795577c

Please sign in to comment.