mirror of
				https://github.com/tormachris/cf-workers-status-page.git
				synced 2025-11-04 04:46:24 +01:00 
			
		
		
		
	Merge pull request #8 from aexvir/aexvir/monitor-filter
feat: add monitor filter field
This commit is contained in:
		@@ -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">
 | 
			
		||||
          <img
 | 
			
		||||
            className="ui middle aligned tiny image"
 | 
			
		||||
            src={config.settings.logo}
 | 
			
		||||
        <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}
 | 
			
		||||
          />
 | 
			
		||||
          {config.settings.title}
 | 
			
		||||
        </h1>
 | 
			
		||||
        </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"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user