diff options
Diffstat (limited to 'src/components/RequestList')
| -rw-r--r-- | src/components/RequestList/RequestList.module.scss | 1 | ||||
| -rw-r--r-- | src/components/RequestList/RequestList.tsx | 253 |
2 files changed, 139 insertions, 115 deletions
diff --git a/src/components/RequestList/RequestList.module.scss b/src/components/RequestList/RequestList.module.scss index 47f36c8..8022978 100644 --- a/src/components/RequestList/RequestList.module.scss +++ b/src/components/RequestList/RequestList.module.scss | |||
| @@ -16,5 +16,4 @@ | |||
| 16 | overflow-y: hidden; | 16 | overflow-y: hidden; |
| 17 | display: flex; | 17 | display: flex; |
| 18 | flex-flow: column nowrap; | 18 | flex-flow: column nowrap; |
| 19 | |||
| 20 | } | 19 | } |
diff --git a/src/components/RequestList/RequestList.tsx b/src/components/RequestList/RequestList.tsx index 95c5b75..6980738 100644 --- a/src/components/RequestList/RequestList.tsx +++ b/src/components/RequestList/RequestList.tsx | |||
| @@ -11,26 +11,29 @@ import classNames from "classnames"; | |||
| 11 | import styles from "./RequestList.module.scss"; | 11 | import styles from "./RequestList.module.scss"; |
| 12 | import RequestSummary from "../RequestSummary/RequestSummary"; | 12 | import RequestSummary from "../RequestSummary/RequestSummary"; |
| 13 | import * as React from "react"; | 13 | import * as React from "react"; |
| 14 | import {useCallback, useContext, useMemo, useState} from "react"; | 14 | import { useCallback, useContext, useMemo, useState } from "react"; |
| 15 | import {Method, RequestResponse} from "../../hooks/useRequests"; | 15 | import { Method, RequestResponse } from "../../hooks/useRequests"; |
| 16 | import {DarkModeContext} from "../../contexts/DarkMode"; | 16 | import { DarkModeContext } from "../../contexts/DarkMode"; |
| 17 | import {Filter} from "../Icons/Filter"; | 17 | import { Filter } from "../Icons/Filter"; |
| 18 | 18 | ||
| 19 | interface ListProps { | 19 | interface ListProps { |
| 20 | requests: RequestResponse[], | 20 | requests: RequestResponse[]; |
| 21 | selectedRequestIndex: number | null | 21 | selectedRequestIndex: number | null; |
| 22 | setSelectedRequestIndex: (index: number) => void | 22 | setSelectedRequestIndex: (index: number) => void; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | type EnabledMethods = { | 25 | type EnabledMethods = { |
| 26 | [method in Method]: boolean | 26 | [method in Method]: boolean; |
| 27 | } | 27 | }; |
| 28 | 28 | ||
| 29 | 29 | export default function RequestList({ | |
| 30 | export default function RequestList({ requests, selectedRequestIndex, setSelectedRequestIndex }: ListProps) { | 30 | requests, |
| 31 | const {darkMode} = useContext(DarkModeContext) | 31 | selectedRequestIndex, |
| 32 | setSelectedRequestIndex, | ||
| 33 | }: ListProps) { | ||
| 34 | const { darkMode } = useContext(DarkModeContext); | ||
| 32 | const [showFilterOptions, setShowFilterOptions] = useState(false); | 35 | const [showFilterOptions, setShowFilterOptions] = useState(false); |
| 33 | const [search, setSearch] = useState(''); | 36 | const [search, setSearch] = useState(""); |
| 34 | const [enableRegex, setEnableRegex] = useState(false); | 37 | const [enableRegex, setEnableRegex] = useState(false); |
| 35 | 38 | ||
| 36 | const [methods, setMethods] = useState<EnabledMethods>({ | 39 | const [methods, setMethods] = useState<EnabledMethods>({ |
| @@ -49,7 +52,7 @@ export default function RequestList({ requests, selectedRequestIndex, setSelecte | |||
| 49 | PUT: enabled, | 52 | PUT: enabled, |
| 50 | PATCH: enabled, | 53 | PATCH: enabled, |
| 51 | DELETE: enabled, | 54 | DELETE: enabled, |
| 52 | } | 55 | }; |
| 53 | 56 | ||
| 54 | if (!enabled) { | 57 | if (!enabled) { |
| 55 | methods[method] = true; | 58 | methods[method] = true; |
| @@ -58,146 +61,168 @@ export default function RequestList({ requests, selectedRequestIndex, setSelecte | |||
| 58 | setMethods(methods); | 61 | setMethods(methods); |
| 59 | }, []); | 62 | }, []); |
| 60 | 63 | ||
| 61 | const enabledMethods: Method[] = useMemo(() => (Object | 64 | const enabledMethods: Method[] = useMemo( |
| 62 | .entries(methods) | 65 | () => |
| 63 | .filter(([method, enabled]) => enabled) | 66 | Object.entries(methods) |
| 64 | .map(([method]) => method) | 67 | .filter(([method, enabled]) => enabled) |
| 65 | ), [methods]); | 68 | .map(([method]) => method), |
| 69 | [methods] | ||
| 70 | ); | ||
| 66 | 71 | ||
| 67 | const methodLabel = useMemo(() => { | 72 | const methodLabel = useMemo(() => { |
| 68 | if (enabledMethods.length == 1) { | 73 | if (enabledMethods.length == 1) { |
| 69 | return enabledMethods[0] | 74 | return enabledMethods[0]; |
| 70 | } else if (enabledMethods.length === 5) { | 75 | } else if (enabledMethods.length === 5) { |
| 71 | return 'ANY' | 76 | return "ANY"; |
| 72 | } else { | 77 | } else { |
| 73 | return 'CUSTOM' | 78 | return "CUSTOM"; |
| 74 | } | 79 | } |
| 75 | }, [enabledMethods]); | 80 | }, [enabledMethods]); |
| 76 | 81 | ||
| 77 | |||
| 78 | |||
| 79 | const filteredRequests = useMemo(() => { | 82 | const filteredRequests = useMemo(() => { |
| 80 | let searchRegex = new RegExp(''); | 83 | let searchRegex = new RegExp(""); |
| 81 | try { | 84 | try { |
| 82 | searchRegex = new RegExp( | 85 | searchRegex = new RegExp( |
| 83 | enableRegex | 86 | enableRegex ? search : search.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), |
| 84 | ? search | 87 | "i" |
| 85 | : search.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), | 88 | ); |
| 86 | 'i'); | 89 | } catch {} |
| 87 | } catch { | ||
| 88 | |||
| 89 | } | ||
| 90 | 90 | ||
| 91 | return ( | 91 | return ( |
| 92 | ( | 92 | requests.map((request, index) => [index, request]).reverse() as [ |
| 93 | requests | 93 | number, |
| 94 | .map((request, index) => [index, request]) | 94 | RequestResponse |
| 95 | .reverse() as [number, RequestResponse][] | 95 | ][] |
| 96 | ) | ||
| 97 | .filter(([index, request]) => ( | ||
| 98 | enabledMethods.length > 0 === null || enabledMethods.includes(request.request.method) | ||
| 99 | )) | ||
| 100 | .filter(([index, request]) => ( | ||
| 101 | search === '' || searchRegex.test(`${request.request.method} ${request.request.path}`) | ||
| 102 | )) | ||
| 103 | ) | 96 | ) |
| 104 | }, [requests, search, enabledMethods, enableRegex]) | 97 | .filter( |
| 98 | ([index, request]) => | ||
| 99 | enabledMethods.length > 0 === null || | ||
| 100 | enabledMethods.includes(request.request.method) | ||
| 101 | ) | ||
| 102 | .filter( | ||
| 103 | ([index, request]) => | ||
| 104 | search === "" || | ||
| 105 | searchRegex.test(`${request.request.method} ${request.request.path}`) | ||
| 106 | ); | ||
| 107 | }, [requests, search, enabledMethods, enableRegex]); | ||
| 105 | 108 | ||
| 106 | return ( | 109 | return ( |
| 107 | <div className={classNames(styles.listContainer, 'd-flex')}> | 110 | <div className={classNames(styles.listContainer, "d-flex")}> |
| 108 | <ListGroup variant="flush" | 111 | <ListGroup |
| 109 | className={classNames('flex-grow-0', 'border-bottom')}> | 112 | variant="flush" |
| 113 | className={classNames("flex-grow-0", "border-bottom")} | ||
| 114 | > | ||
| 110 | <ListGroup.Item> | 115 | <ListGroup.Item> |
| 111 | <InputGroup> | 116 | <InputGroup> |
| 112 | <DropdownButton variant="primary" title={methodLabel}> | 117 | <DropdownButton variant="primary" title={methodLabel}> |
| 113 | <Dropdown.Item | 118 | <Dropdown.Item onClick={() => toggleMethods(null)}> |
| 114 | onClick={() => toggleMethods(null)}>ANY</Dropdown.Item> | 119 | ANY |
| 115 | <Dropdown.Divider/> | 120 | </Dropdown.Item> |
| 116 | <Dropdown.Item | 121 | <Dropdown.Divider /> |
| 117 | onClick={() => toggleMethods('GET')}>GET</Dropdown.Item> | 122 | <Dropdown.Item onClick={() => toggleMethods("GET")}> |
| 118 | <Dropdown.Item | 123 | GET |
| 119 | onClick={() => toggleMethods('POST')}>POST</Dropdown.Item> | 124 | </Dropdown.Item> |
| 120 | <Dropdown.Item | 125 | <Dropdown.Item onClick={() => toggleMethods("POST")}> |
| 121 | onClick={() => toggleMethods('PUT')}>PUT</Dropdown.Item> | 126 | POST |
| 122 | <Dropdown.Item | 127 | </Dropdown.Item> |
| 123 | onClick={() => toggleMethods('PATCH')}>PATCH</Dropdown.Item> | 128 | <Dropdown.Item onClick={() => toggleMethods("PUT")}> |
| 124 | <Dropdown.Item | 129 | PUT |
| 125 | onClick={() => toggleMethods('DELETE')}>DELETE</Dropdown.Item> | 130 | </Dropdown.Item> |
| 131 | <Dropdown.Item onClick={() => toggleMethods("PATCH")}> | ||
| 132 | PATCH | ||
| 133 | </Dropdown.Item> | ||
| 134 | <Dropdown.Item onClick={() => toggleMethods("DELETE")}> | ||
| 135 | DELETE | ||
| 136 | </Dropdown.Item> | ||
| 126 | </DropdownButton> | 137 | </DropdownButton> |
| 127 | <Form.Control type="text" className='border-secondary' | 138 | <Form.Control |
| 128 | value={search} placeholder="Search..." | 139 | type="text" |
| 129 | onChange={({target}) => setSearch(target.value)}/> | 140 | className="border-secondary" |
| 141 | value={search} | ||
| 142 | placeholder="Search..." | ||
| 143 | onChange={({ target }) => setSearch(target.value)} | ||
| 144 | /> | ||
| 130 | <Button | 145 | <Button |
| 131 | variant={showFilterOptions ? 'secondary' : 'outline-secondary'} | 146 | variant={showFilterOptions ? "secondary" : "outline-secondary"} |
| 132 | onClick={() => setShowFilterOptions(true)}> | 147 | onClick={() => setShowFilterOptions(true)} |
| 133 | <Filter/> | 148 | > |
| 149 | <Filter /> | ||
| 134 | </Button> | 150 | </Button> |
| 135 | </InputGroup> | 151 | </InputGroup> |
| 136 | </ListGroup.Item> | 152 | </ListGroup.Item> |
| 137 | </ListGroup> | 153 | </ListGroup> |
| 138 | <ListGroup | 154 | <ListGroup |
| 139 | variant='flush' | 155 | variant="flush" |
| 140 | as="ul" | 156 | as="ul" |
| 141 | className={classNames(styles.list, 'flex-grow-1')} | 157 | className={classNames(styles.list, "flex-grow-1")} |
