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} + + + +
+ {title} +
{children}
+
+
+ + )} +
+ ) +} 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 - - - -
- Event types -
- {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' - /> -
-
- -
-
- ))} -
-
-
- - )} -
- - {({ open }) => ( - <> - - Modules - - - -
- Modules -
- {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' - /> -
-
- -
-
- ))} -
-
-
- - )} -
+ + {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', -}