diff --git a/console/client/src/components/CodeBlock.tsx b/console/client/src/components/CodeBlock.tsx
index 29de3568d0..976f9e6793 100644
--- a/console/client/src/components/CodeBlock.tsx
+++ b/console/client/src/components/CodeBlock.tsx
@@ -13,6 +13,7 @@ interface Props {
export const CodeBlock = ({ code, language, maxHeight }: Props) => {
useEffect(() => {
+ hljs.configure({ ignoreUnescapedHTML: true })
hljs.registerLanguage('graphql', graphql)
hljs.registerLanguage('json', json)
hljs.registerLanguage('go', go)
@@ -21,7 +22,7 @@ export const CodeBlock = ({ code, language, maxHeight }: Props) => {
return (
- {code}
+ {code}
)
}
diff --git a/console/client/src/features/logs/LogLevelBadge.tsx b/console/client/src/features/logs/LogLevelBadge.tsx
new file mode 100644
index 0000000000..3a40702004
--- /dev/null
+++ b/console/client/src/features/logs/LogLevelBadge.tsx
@@ -0,0 +1,11 @@
+import { logLevelBadge, logLevelText } from './log.utils'
+
+export const LogLevelBadge = ({ logLevel }: { logLevel: number }) => {
+ return (
+
+ {logLevelText[logLevel]}
+
+ )
+}
diff --git a/console/client/src/features/logs/LogLevelBadgeSmall.tsx b/console/client/src/features/logs/LogLevelBadgeSmall.tsx
new file mode 100644
index 0000000000..652859af63
--- /dev/null
+++ b/console/client/src/features/logs/LogLevelBadgeSmall.tsx
@@ -0,0 +1,11 @@
+import { logLevelBadge, logLevelCharacter } from './log.utils'
+
+export const LogLevelBadgeSmall = ({ logLevel }: { logLevel: number }) => {
+ return (
+
+ {`${logLevelCharacter[logLevel]}`}
+
+ )
+}
diff --git a/console/client/src/features/logs/log.utils.tsx b/console/client/src/features/logs/log.utils.tsx
new file mode 100644
index 0000000000..c7af586a51
--- /dev/null
+++ b/console/client/src/features/logs/log.utils.tsx
@@ -0,0 +1,31 @@
+export const logLevelCharacter: { [key: number]: string } = {
+ 1: 't',
+ 5: 'd',
+ 9: 'i',
+ 13: 'w',
+ 17: 'e',
+}
+
+export const logLevelText: { [key: number]: string } = {
+ 1: 'Trace',
+ 5: 'Debug',
+ 9: 'Info',
+ 13: 'Warn',
+ 17: 'Error',
+}
+
+export const logLevelColor: { [key: number]: string } = {
+ 1: 'text-gray-400 dark:text-gray-400',
+ 5: 'text-blue-400 dark:text-blue-400',
+ 9: 'text-green-500 dark:text-green-300',
+ 13: 'text-yellow-400 dark:text-yellow-300',
+ 17: 'text-red-400 dark:text-red-400',
+}
+
+export const logLevelBadge: { [key: number]: string } = {
+ 1: `${logLevelColor[1]} bg-blue-300/10 dark:bg-blue-700/30`,
+ 5: `${logLevelColor[5]} bg-blue-400/10 dark:bg-blue-800/30`,
+ 9: `${logLevelColor[9]} bg-green-400/30 dark:bg-green-700/30`,
+ 13: `${logLevelColor[13]} bg-yellow-400/10 dark:bg-yellow-600/30`,
+ 17: `${logLevelColor[17]} bg-red-500/10 dark:bg-red-700/30`,
+}
diff --git a/console/client/src/features/timeline/TimelineIcon.tsx b/console/client/src/features/timeline/TimelineIcon.tsx
index d610d75ec9..ab01f72e6e 100644
--- a/console/client/src/features/timeline/TimelineIcon.tsx
+++ b/console/client/src/features/timeline/TimelineIcon.tsx
@@ -1,47 +1,31 @@
import { ListBulletIcon, PhoneArrowDownLeftIcon, PhoneIcon, RocketLaunchIcon } from '@heroicons/react/24/outline'
import { TimelineEvent } from '../../protos/xyz/block/ftl/v1/console/console_pb'
+import { LogLevelBadgeSmall } from '../logs/LogLevelBadgeSmall'
interface Props {
entry: TimelineEvent
}
-export const logLevelIconColor: { [key: number]: string } = {
- 1: 'text-indigo-600 dark:text-indigo-600',
- 5: 'text-indigo-600 dark:text-indigo-600',
- 9: 'text-green-500 dark:text-green-400',
- 13: 'text-yellow-400 dark:text-yellow-300',
- 17: 'text-red-500 dark:text-red-400',
-}
-
export const TimelineIcon = ({ entry }: Props) => {
- const iconColor = (entry: TimelineEvent) => {
- switch (entry.entry.case) {
- case 'call':
- return entry.entry.value.error ? 'text-red-600' : 'text-indigo-600'
- case 'log':
- return `${logLevelIconColor[entry.entry.value.logLevel]}`
- default:
- return 'text-indigo-600'
- }
- }
-
const icon = (entry: TimelineEvent) => {
- const style = 'h4 w-4'
+ const style = 'h4 w-4 text-indigo-600'
switch (entry.entry.case) {
- case 'call':
+ case 'call': {
+ const textColor = entry.entry.value.error ? 'text-red-600' : 'text-indigo-600'
return entry.entry.value.sourceVerbRef ? (
-
+
) : (
)
+ }
case 'deployment':
return
case 'log':
- return
+ return
default:
return
}
}
- return {icon(entry)}
+ return {icon(entry)}
}
diff --git a/console/client/src/features/timeline/details/TimelineLogDetails.tsx b/console/client/src/features/timeline/details/TimelineLogDetails.tsx
index c08adc3292..4e2515d6d5 100644
--- a/console/client/src/features/timeline/details/TimelineLogDetails.tsx
+++ b/console/client/src/features/timeline/details/TimelineLogDetails.tsx
@@ -1,8 +1,8 @@
import { Timestamp } from '@bufbuild/protobuf'
import { CodeBlock } from '../../../components/CodeBlock'
import { LogEntry, TimelineEvent } from '../../../protos/xyz/block/ftl/v1/console/console_pb'
-import { classNames } from '../../../utils/react.utils'
-import { logLevelBadge, logLevelText, textColor } from '../../../utils/style.utils'
+import { textColor } from '../../../utils/style.utils'
+import { LogLevelBadge } from '../../logs/LogLevelBadge'
import { TimelineTimestamp } from './TimelineTimestamp'
interface Props {
@@ -27,14 +27,7 @@ export const TimelineLogDetails = ({ entry, log }: Props) => {
Level
-
- {logLevelText[log.logLevel]}
-
+
diff --git a/console/client/src/features/timeline/filters/FilterPanelSection.tsx b/console/client/src/features/timeline/filters/FilterPanelSection.tsx
new file mode 100644
index 0000000000..782eeae8df
--- /dev/null
+++ b/console/client/src/features/timeline/filters/FilterPanelSection.tsx
@@ -0,0 +1,32 @@
+import { Disclosure } from '@headlessui/react'
+import { ChevronUpIcon } from '@heroicons/react/20/solid'
+import { textColor } from '../../../utils'
+
+interface Props {
+ title: string
+ children: React.ReactNode
+ defaultOpen?: boolean
+}
+
+export const FilterPanelSection = ({ title, children, defaultOpen = true }: Props) => {
+ return (
+
+ {({ open }) => (
+ <>
+
+ {title}
+
+
+
+
+
+ >
+ )}
+
+ )
+}
diff --git a/console/client/src/features/timeline/filters/LogLevelsFilter.tsx b/console/client/src/features/timeline/filters/LogLevelsFilter.tsx
index 1b2a9065ca..741a7af258 100644
--- a/console/client/src/features/timeline/filters/LogLevelsFilter.tsx
+++ b/console/client/src/features/timeline/filters/LogLevelsFilter.tsx
@@ -1,7 +1,8 @@
import { Popover, Transition } from '@headlessui/react'
import { ChevronDownIcon } from '@heroicons/react/20/solid'
import { Fragment } from 'react'
-import { logLevelText, textColor } from '../../../utils'
+import { textColor } from '../../../utils'
+import { logLevelText } from '../../logs/log.utils'
const logLevels = [1, 5, 9, 13, 17]
diff --git a/console/client/src/features/timeline/filters/TimelineFilterPanel.tsx b/console/client/src/features/timeline/filters/TimelineFilterPanel.tsx
index 2ec705cd3b..d06ea4c99d 100644
--- a/console/client/src/features/timeline/filters/TimelineFilterPanel.tsx
+++ b/console/client/src/features/timeline/filters/TimelineFilterPanel.tsx
@@ -1,8 +1,11 @@
-import { Disclosure } from '@headlessui/react'
-import { ChevronUpIcon } from '@heroicons/react/20/solid'
+import { PhoneIcon, RocketLaunchIcon } from '@heroicons/react/24/outline'
import React from 'react'
+import { LogLevel } from '../../../protos/xyz/block/ftl/v1/console/console_pb'
import { modulesContext } from '../../../providers/modules-provider'
import { textColor } from '../../../utils'
+import { LogLevelBadgeSmall } from '../../logs/LogLevelBadgeSmall'
+import { logLevelColor } from '../../logs/log.utils'
+import { FilterPanelSection } from './FilterPanelSection'
const EVENT_TYPES: Record
= {
call: 'Call',
@@ -10,18 +13,30 @@ const EVENT_TYPES: Record = {
deployment: 'Deployment',
}
-const headerStyles = 'bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600'
+const EVENT_TYPE_ICON: Record = {
+ call: ,
+ log: ,
+ deployment: ,
+}
+
+const LOG_LEVELS: Record = {
+ 1: 'Trace',
+ 5: 'Debug',
+ 9: 'Info',
+ 13: 'Warn',
+ 17: 'Error',
+}
export const TimelineFilterPanel = () => {
const modules = React.useContext(modulesContext)
const [selectedEventTypes, setSelectedEventTypes] = React.useState(Object.keys(EVENT_TYPES))
const [selectedModules, setSelectedModules] = React.useState([])
+ const [selectedLogLevel, setSelectedLogLevel] = React.useState(1)
React.useEffect(() => {
if (selectedModules.length === 0) {
setSelectedModules(modules.modules.map((module) => module.name))
}
- console.log(modules)
}, [modules])
const handleTypeChanged = (eventType: string, checked: boolean) => {
@@ -40,86 +55,83 @@ export const TimelineFilterPanel = () => {
}
}
+ const handleLogLevelChanged = (logLevel: string) => {
+ setSelectedLogLevel(Number(logLevel))
+ }
+
return (
-
- {({ open }) => (
- <>
-
- Event types
-
-
-
-
-
- >
- )}
-
-
- {({ open }) => (
- <>
-
- Modules
-
-
-
-
-
- >
- )}
-
+
+ {Object.keys(EVENT_TYPES).map((key) => (
+
+
+ handleTypeChanged(key, e.target.checked)}
+ className='h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 cursor-pointer'
+ />
+
+
+
+
+
+ ))}
+
+
+
+ {Object.keys(LOG_LEVELS).map((key) => (
+
+
+ handleLogLevelChanged(key)}
+ className='h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 cursor-pointer'
+ />
+
+
+
+
+
+ ))}
+
+
+
+ {modules.modules.map((module) => (
+
+
+ handleModuleChanged(module.name, e.target.checked)}
+ className='h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 cursor-pointer'
+ />
+
+
+
+
+
+ ))}
+
diff --git a/console/client/src/utils/style.utils.ts b/console/client/src/utils/style.utils.ts
index 023e4b77d1..7f77702c09 100644
--- a/console/client/src/utils/style.utils.ts
+++ b/console/client/src/utils/style.utils.ts
@@ -7,29 +7,3 @@ export const textColor = 'dark:text-white text-gray-800'
export const lightTextColor = 'text-gray-500'
export const navColor = 'dark:bg-indigo-700 bg-indigo-700'
export const borderColor = 'dark:ring-gray-600 ring-gray-300'
-
-export const statuses = {
- offline: 'text-gray-500 bg-gray-100/10',
- online: 'text-green-400 bg-green-400/10',
- error: 'text-rose-400 bg-rose-400/10',
-}
-export const environments = {
- Staging: 'text-gray-400 bg-gray-400/10 ring-gray-400/20',
- Production: 'text-indigo-400 bg-indigo-400/10 ring-indigo-400/30',
-}
-
-export const logLevelText: { [key: number]: string } = {
- 1: 'Trace',
- 5: 'Debug',
- 9: 'Info',
- 13: 'Warn',
- 17: 'Error',
-}
-
-export const logLevelBadge: { [key: number]: string } = {
- 1: 'text-blue-350 bg-blue-300/10 dark:text-blue-300 dark:bg-blue-700/10',
- 5: 'text-blue-350 bg-blue-400/10 dark:text-blue-300 dark:bg-blue-800/10',
- 9: 'text-green-600 bg-green-400/30 dark:text-green-300 dark:bg-green-700/10',
- 13: 'text-yellow-400 bg-yellow-400/10 dark:text-yellow-300 dark:bg-yellow-600/10',
- 17: 'text-red-500 bg-red-500/10 dark:text-red-400 dark:bg-red-700/10',
-}