mirror of
https://github.com/tormachris/cf-workers-status-page.git
synced 2024-11-23 22:45:43 +01:00
feat: add monitor filter field
This commit is contained in:
parent
9e178fe386
commit
e2c6a6a538
@ -13,6 +13,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"flareact": "^0.7.1",
|
||||
"laco": "^1.2.1",
|
||||
"laco-react": "^1.1.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1"
|
||||
},
|
||||
|
@ -5,11 +5,28 @@ import {
|
||||
getLastUpdate,
|
||||
getMonitors,
|
||||
getMonitorsHistory,
|
||||
useKeyPress,
|
||||
} from '../src/functions/helpers'
|
||||
|
||||
import config from '../config.yaml'
|
||||
import MonitorStatusLabel from '../src/components/monitorStatusLabel'
|
||||
import MonitorStatusHeader from '../src/components/monitorStatusHeader'
|
||||
import MonitorFilter from '../src/components/monitorFilter'
|
||||
|
||||
import { Store } from 'laco'
|
||||
import { useStore } from 'laco-react'
|
||||
|
||||
const MonitorStore = new Store(
|
||||
{
|
||||
monitors: config.monitors,
|
||||
visible: config.monitors,
|
||||
activeFilter: false
|
||||
}
|
||||
)
|
||||
|
||||
const filterByTerm = (term) => MonitorStore.set(
|
||||
state => ({ visible: state.monitors.filter((monitor) => monitor.name.toLowerCase().includes(term)) })
|
||||
)
|
||||
|
||||
export async function getEdgeProps() {
|
||||
// get KV data
|
||||
@ -50,6 +67,9 @@ export default function Index({
|
||||
monitorsOperational,
|
||||
kvLastUpdate,
|
||||
}) {
|
||||
const state = useStore(MonitorStore)
|
||||
const slash = useKeyPress('/')
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Head>
|
||||
@ -62,18 +82,24 @@ export default function Index({
|
||||
<link rel="stylesheet" href="./main.css" />
|
||||
</Head>
|
||||
<div className="ui basic segment container">
|
||||
<h1 className="ui huge title header">
|
||||
<div className="horizontal flex between">
|
||||
<h1 className="ui huge marginless title header">
|
||||
<img
|
||||
className="ui middle aligned tiny image"
|
||||
src={config.settings.logo}
|
||||
/>
|
||||
{config.settings.title}
|
||||
</h1>
|
||||
<MonitorFilter
|
||||
active={slash}
|
||||
callback={filterByTerm}
|
||||
/>
|
||||
</div>
|
||||
<MonitorStatusHeader
|
||||
operational={monitorsOperational}
|
||||
lastUpdate={kvLastUpdate}
|
||||
/>
|
||||
{config.monitors.map((monitor, key) => {
|
||||
{state.visible.map((monitor, key) => {
|
||||
return (
|
||||
<div key={key} className="ui segment">
|
||||
<div
|
||||
|
42
src/components/monitorFilter.js
Normal file
42
src/components/monitorFilter.js
Normal file
@ -0,0 +1,42 @@
|
||||
import config from '../../config.yaml'
|
||||
import { useState } from 'react'
|
||||
|
||||
export default function MonitorFilter({ active, callback }) {
|
||||
const [input, setInput] = useState('')
|
||||
|
||||
const handleInput = (event) => {
|
||||
// ignore focus trigger
|
||||
if (event.target.value === '/') {
|
||||
return
|
||||
}
|
||||
setInput(event.target.value)
|
||||
callback(event.target.value)
|
||||
}
|
||||
|
||||
const handleKeyDown = (event) => {
|
||||
// blur input field on escape
|
||||
if (event.keyCode === 27) {
|
||||
event.target.blur()
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ui search">
|
||||
<div className="ui icon input">
|
||||
<input
|
||||
className="prompt"
|
||||
type="text"
|
||||
value={input}
|
||||
onInput={handleInput}
|
||||
onKeyDown={handleKeyDown}
|
||||
placeholder="Tap '/' to search"
|
||||
tabIndex={0}
|
||||
ref={
|
||||
(e) => e && active && e.focus()
|
||||
}
|
||||
/>
|
||||
<i className="search icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import config from '../../config.yaml'
|
||||
import {useEffect, useState} from 'react'
|
||||
|
||||
export async function getMonitors() {
|
||||
const monitors = await listKV('s_')
|
||||
@ -115,3 +116,31 @@ export async function notifySlack(monitor, newMetadata) {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
})
|
||||
}
|
||||
|
||||
export function useKeyPress(targetKey) {
|
||||
const [keyPressed, setKeyPressed] = useState(false)
|
||||
|
||||
function downHandler({ key }) {
|
||||
if (key === targetKey) {
|
||||
setKeyPressed(true);
|
||||
}
|
||||
}
|
||||
|
||||
const upHandler = ({ key }) => {
|
||||
if (key === targetKey) {
|
||||
setKeyPressed(false);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('keydown', downHandler);
|
||||
window.addEventListener('keyup', upHandler);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('keydown', downHandler);
|
||||
window.removeEventListener('keyup', upHandler);
|
||||
};
|
||||
}, [])
|
||||
|
||||
return keyPressed
|
||||
}
|
||||
|
10
yarn.lock
10
yarn.lock
@ -3902,6 +3902,16 @@ kind-of@^6.0.0, kind-of@^6.0.2:
|
||||
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
|
||||
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
|
||||
|
||||
laco-react@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/laco-react/-/laco-react-1.1.0.tgz#8572117aabd245e9ff0000aab534c0f817da8238"
|
||||
integrity sha512-RbN7dFUH7RsNpRMB46gWSjEMXo7WDhgkKl8HXpxn1o/bJItHj7FT0VsIWF963mrvORncIgI7bnZJ6KPcHV8fvA==
|
||||
|
||||
laco@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/laco/-/laco-1.2.1.tgz#4acf24ab4ea7b2983d10c2fd982208e96a315158"
|
||||
integrity sha512-fw3vWTR1L/u/XTReyBQt3bnhylMLMqp+YoIFEr52bb9NqRnwPcvTQuFH0TRMyvg0Zucbx+eRViO4wxoij6xzDg==
|
||||
|
||||
last-call-webpack-plugin@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555"
|
||||
|
Loading…
Reference in New Issue
Block a user