handleEntryClicked(entry)}
@@ -139,7 +110,7 @@ export const Timeline = () => {
|
-
+ |
{formatTimestampShort(entry.timeStamp)}
|
diff --git a/console/client/src/features/timeline/TimelinePage.tsx b/console/client/src/features/timeline/TimelinePage.tsx
new file mode 100644
index 0000000000..11c01ff140
--- /dev/null
+++ b/console/client/src/features/timeline/TimelinePage.tsx
@@ -0,0 +1,21 @@
+import { Timeline as TimelineIcon } from '@mui/icons-material'
+import { PageHeader } from '../../components/PageHeader'
+import { Timeline } from './Timeline'
+import { TimelineFilterPanel } from './filters/TimelineFilterPanel'
+import { TimelineTimeControls } from './filters/TimelineTimeControls'
+
+export const TimelinePage = () => {
+ return (
+ <>
+ } title='Events'>
+
+
+
+ >
+ )
+}
diff --git a/console/client/src/features/timeline/filters/TimelineFilterPanel.tsx b/console/client/src/features/timeline/filters/TimelineFilterPanel.tsx
new file mode 100644
index 0000000000..2ec705cd3b
--- /dev/null
+++ b/console/client/src/features/timeline/filters/TimelineFilterPanel.tsx
@@ -0,0 +1,127 @@
+import { Disclosure } from '@headlessui/react'
+import { ChevronUpIcon } from '@heroicons/react/20/solid'
+import React from 'react'
+import { modulesContext } from '../../../providers/modules-provider'
+import { textColor } from '../../../utils'
+
+const EVENT_TYPES: Record = {
+ call: 'Call',
+ log: 'Log',
+ deployment: 'Deployment',
+}
+
+const headerStyles = 'bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600'
+
+export const TimelineFilterPanel = () => {
+ const modules = React.useContext(modulesContext)
+ const [selectedEventTypes, setSelectedEventTypes] = React.useState(Object.keys(EVENT_TYPES))
+ const [selectedModules, setSelectedModules] = React.useState([])
+
+ React.useEffect(() => {
+ if (selectedModules.length === 0) {
+ setSelectedModules(modules.modules.map((module) => module.name))
+ }
+ console.log(modules)
+ }, [modules])
+
+ const handleTypeChanged = (eventType: string, checked: boolean) => {
+ if (checked) {
+ setSelectedEventTypes((prev) => [...prev, eventType])
+ } else {
+ setSelectedEventTypes((prev) => prev.filter((filter) => filter !== eventType))
+ }
+ }
+
+ const handleModuleChanged = (moduleName: string, checked: boolean) => {
+ if (checked) {
+ setSelectedModules((prev) => [...prev, moduleName])
+ } else {
+ setSelectedModules((prev) => prev.filter((filter) => filter !== moduleName))
+ }
+ }
+
+ return (
+
+
+
+
+ {({ open }) => (
+ <>
+
+ Event types
+
+
+
+
+
+ >
+ )}
+
+
+ {({ open }) => (
+ <>
+
+ Modules
+
+
+
+
+
+ >
+ )}
+
+
+
+
+ )
+}
diff --git a/console/client/src/features/timeline/filters/TimelineTimeControls.tsx b/console/client/src/features/timeline/filters/TimelineTimeControls.tsx
new file mode 100644
index 0000000000..858c52818b
--- /dev/null
+++ b/console/client/src/features/timeline/filters/TimelineTimeControls.tsx
@@ -0,0 +1,114 @@
+import { Listbox, Transition } from '@headlessui/react'
+import { CheckIcon, ChevronUpDownIcon } from '@heroicons/react/24/outline'
+import { NavigateBefore, NavigateNext, PlayArrow } from '@mui/icons-material'
+import React, { Fragment } from 'react'
+import { bgColor, borderColor, classNames, panelColor, textColor } from '../../../utils'
+
+interface TimeRange {
+ label: string
+ value: number
+}
+
+export const TIME_RANGES: Record = {
+ tail: { label: 'Live tail', value: 0 },
+ '5m': { label: 'Past 5 minutes', value: 5 * 60 * 1000 },
+ '30m': { label: 'Past 30 minutes', value: 30 * 60 * 1000 },
+ '1h': { label: 'Past 1 hour', value: 60 * 60 * 1000 },
+ '24h': { label: 'Past 24 hours', value: 24 * 60 * 60 * 1000 },
+}
+
+export const TimelineTimeControls = () => {
+ const [selected, setSelected] = React.useState(TIME_RANGES['tail'])
+
+ return (
+ <>
+
+
+ {({ open }) => (
+ <>
+
+
+ {selected.label}
+
+
+
+
+
+
+
+ {Object.keys(TIME_RANGES).map((key) => {
+ const timeRange = TIME_RANGES[key]
+ return (
+
+ classNames(
+ active ? 'bg-indigo-600 text-white' : `${textColor}`,
+ 'relative cursor-pointer select-none py-2 pl-3 pr-9',
+ )
+ }
+ value={timeRange}
+ >
+ {({ selected, active }) => (
+ <>
+
+ {timeRange.label}
+
+
+ {selected ? (
+
+
+
+ ) : null}
+ >
+ )}
+
+ )
+ })}
+
+
+
+ >
+ )}
+
+
+
+
+
+
+
+ >
+ )
+}
diff --git a/console/client/src/layout/Layout.tsx b/console/client/src/layout/Layout.tsx
index ec31c9eab8..780bb3f56f 100644
--- a/console/client/src/layout/Layout.tsx
+++ b/console/client/src/layout/Layout.tsx
@@ -8,7 +8,7 @@ export const Layout = () => {
-
+
diff --git a/console/client/src/layout/Navigation.tsx b/console/client/src/layout/Navigation.tsx
index 54ab8c345b..e96051a2b0 100644
--- a/console/client/src/layout/Navigation.tsx
+++ b/console/client/src/layout/Navigation.tsx
@@ -1,4 +1,4 @@
-import { Schema, Timeline, ViewModuleSharp } from '@mui/icons-material'
+import { Schema, Timeline, ViewModuleRounded } from '@mui/icons-material'
import { useContext } from 'react'
import { Link, NavLink } from 'react-router-dom'
import { DarkModeSwitch } from '../components/DarkModeSwitch'
@@ -7,7 +7,7 @@ import { classNames } from '../utils'
const navigation = [
{ name: 'Events', href: '/events', icon: Timeline },
- { name: 'Modules', href: '/modules', icon: ViewModuleSharp },
+ { name: 'Modules', href: '/modules', icon: ViewModuleRounded },
{ name: 'Graph', href: '/graph', icon: Schema },
]
@@ -17,8 +17,8 @@ export const Navigation = () => {
return (
|