direct use of /v1/rule/targets:
only devices are used:
devices.map(device =>
<Option key={device.mac}>
<Icon type={getDeviceIcon(device)} />| /* define context */ | |
| import React, { createContext } from 'react' | |
| // the biggest limitation of context is there's no way of refering to & setting state when defining context | |
| // actions can only be implemented inside context provider | |
| const LayoutContext = createContext<{ | |
| collapsed: boolean, | |
| toggleCollapsed: () => void | |
| }>({ |
| // naive example code for "topic based publish/subscribe model" | |
| // this is just to illustrate the idea, feature is incomplete, do NOT use in production | |
| // reference: https://github.com/mroderick/PubSubJS | |
| type TopicHandler = (data?: any) => void; | |
| interface ISubscriber { | |
| topic: string; | |
| handler: TopicHandler | |
| } |
| // ref: https://www.patterns.dev/posts/render-props-pattern/ | |
| // note: in many cases, render props can be replaced by hooks | |
| import { FC, useState } from "react"; | |
| interface IContainerProps { | |
| children: (bg: "silver" | "gold") => React.ReactNode; | |
| } | |
| const Container: FC<IContainerProps> = ({ children }) => { |
| import { useState, FC } from "react"; | |
| const App: FC = () => { | |
| const [number, setNumber] = useState(1); | |
| const nextNumber = number + 1; | |
| function handleIncrease() { | |
| setNumber((num) => num + 1); | |
| console.log("current number is", number); // still the old number |
| /** | |
| * example of a wrapper of browser's native fetch method | |
| * Assumptions: | |
| * 1. server uses JWT & bearer token for authorization | |
| * 2. client stores auth token in local storage | |
| * 3. response's content type | |
| * a. "application/json" for normal response | |
| * b. "application/octet-stream" for file download | |
| * c. "text/plain" when error | |
| * 4. server returns 401 when auth token is invalid |
| import { FC } from "react"; | |
| const Home: FC = () => { | |
| return ( | |
| <div> | |
| <header> | |
| <img src="/images/site-logo.svg" alt="logo" /> | |
| </header> | |
| <main |
| // this works but is quite messy and error prone | |
| function getUrl(server: string, path: string, name: string, age: number): string { | |
| const trimmedServer = server.endsWith("/") ? server.slice(0, -1) : server; // remove trialing slash if any | |
| const origin = trimmedServer.startsWith("http") ? trimmedServer : `https://${trimmedServer}`; // add protocol if needed | |
| const trimmedPath = path.endsWith("/") ? path.slice(0, -1) : path; // remove trialing slash if any | |
| const realPath = trimmedPath.startsWith("/") ? trimmedPath : `/${trimmedPath}`; // add slash to begining if needed | |
| const params = new URLSearchParams({ | |
| name: name, | |
| age: String(age) |
| const fs = require('fs'); | |
| fs.readFile('content.txt', 'utf-8', (err, data) => { | |
| if (err) { | |
| console.log(err) | |
| return; | |
| } | |
| let charsCount = 0; | |
| let totalBytes = 0 | |
| Array.from(data).forEach(char => { |