diff --git a/ui/src/components/map/EnrichedLayerFeatures.tsx b/ui/src/components/map/EnrichedLayerFeatures.tsx index 2ee987d4..0cfaf80b 100644 --- a/ui/src/components/map/EnrichedLayerFeatures.tsx +++ b/ui/src/components/map/EnrichedLayerFeatures.tsx @@ -122,7 +122,7 @@ const EnrichedSymbolSource = (props: EnrichedFeaturesProps) => { layout={{ "icon-image": ["coalesce", ["get", "icon"], "default_marker"], "icon-allow-overlap": true, - "icon-size": ["interpolate", ["linear"], ["zoom"], 12, 0.1, 17, 1], + "icon-size": ["interpolate", ["linear"], ["zoom"], 12, 0.1, 17, 1.4], "icon-rotation-alignment": "map", "icon-pitch-alignment": "map", "icon-rotate": ["coalesce", ["get", "iconRotation"], 0], diff --git a/ui/src/utils/ReloadSWPrompt.tsx b/ui/src/utils/ReloadSWPrompt.tsx index 8d0dd951..ba2b7523 100644 --- a/ui/src/utils/ReloadSWPrompt.tsx +++ b/ui/src/utils/ReloadSWPrompt.tsx @@ -11,10 +11,11 @@ export function ReloadPrompt() { } = useRegisterSW({ onRegistered(r) { console.log("SW Registered: " + r); - r && - setInterval(() => { - r.update(); - }, intervalMS); + if (r === undefined) return; + + setInterval(() => { + r.update(); + }, intervalMS); setOfflineReady(true); }, onRegisterError(error) { diff --git a/ui/src/utils/useDebounce.tsx b/ui/src/utils/useDebounce.tsx index ccc87f6c..eb2e16fb 100644 --- a/ui/src/utils/useDebounce.tsx +++ b/ui/src/utils/useDebounce.tsx @@ -1,25 +1,22 @@ import { useEffect, useState } from "react"; -// Hook +// eslint-disable-next-line @typescript-eslint/no-explicit-any export function useDebounce(value: any, delay: number) { - // State and setters for debounced value - const [debouncedValue, setDebouncedValue] = useState(value); - useEffect( - () => { - // Update debounced value after delay - const handler = setTimeout(() => { - setDebouncedValue(value); - }, delay); - // Cancel the timeout if value changes (also on delay change or unmount) - // This is how we prevent debounced value from updating if value is changed ... - // .. within the delay period. Timeout gets cleared and restarted. - return () => { - clearTimeout(handler); - }; - }, - [value, delay] - ); - return debouncedValue; + // State and setters for debounced value + const [debouncedValue, setDebouncedValue] = useState(value); + useEffect(() => { + // Update debounced value after delay + const handler = setTimeout(() => { + setDebouncedValue(value); + }, delay); + // Cancel the timeout if value changes (also on delay change or unmount) + // This is how we prevent debounced value from updating if value is changed ... + // .. within the delay period. Timeout gets cleared and restarted. + return () => { + clearTimeout(handler); + }; + }, [value, delay]); + return debouncedValue; } -export default useDebounce; \ No newline at end of file +export default useDebounce; diff --git a/ui/src/utils/useLocalStorage.tsx b/ui/src/utils/useLocalStorage.tsx index 7a895efe..3dbf9184 100644 --- a/ui/src/utils/useLocalStorage.tsx +++ b/ui/src/utils/useLocalStorage.tsx @@ -143,7 +143,6 @@ export function useLocalStorage( const value = readValue(); setValue(value); setStoredValue(value); - // eslint-disable-next-line react-hooks/exhaustive-deps }, [key]); const handleStorageChange = useCallback( diff --git a/ui/src/views/incident/List.tsx b/ui/src/views/incident/List.tsx index d81dbe58..c77be419 100644 --- a/ui/src/views/incident/List.tsx +++ b/ui/src/views/incident/List.tsx @@ -6,7 +6,7 @@ import { faEyeLowVision, faFolderClosed, faFolderOpen, - faPlusCircle + faPlusCircle, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import classNames from "classnames"; @@ -19,24 +19,21 @@ import { useNavigate } from "react-router-dom"; import { Incident, IncidentListData } from "../../types"; import { CloseIncident, GetIncidentDetails, GetIncidents } from "./graphql"; - function List() { const [filterClosed, setFilterClosed] = useState(true); const navigate = useNavigate(); const { t } = useTranslation(); - const { loading, error, data } = useQuery(GetIncidents, - { - pollInterval: 10000, - } - ); + const { loading, error, data } = useQuery(GetIncidents, { + pollInterval: 10000, + }); if (error) return
{error.message}
; if (loading) return ; return (
-

{t('incidents')}

+

{t("incidents")}

- { - incidents.map((incident) => ( - - )) - } -
- ) + {incidents.map((incident) => ( + + ))} + + ); } -function IncidentCard(props: { incident: Incident, closeIncident: any }) { - const { incident, closeIncident } = props; +function IncidentCard(props: { incident: Incident }) { + const { incident } = props; const navigate = useNavigate(); + const [closeIncident] = useMutation(CloseIncident, { + refetchQueries: [{ query: GetIncidents }, { query: GetIncidentDetails }], + }); const cardClass = classNames({ card: true, "mb-3": true, - "has-background-primary-light": incident.closedAt + "has-background-primary-light": incident.closedAt, }); return ( -
+

{incident.name}

- {t('location')}: {incident.location.name} + {t("location")}: + {incident.location.name}
- {t('createdAt')}: {dayjs(incident.createdAt).format("LLL")} + {t("createdAt")}: + {dayjs(incident.createdAt).format("LLL")}
- {incident.closedAt &&
- {t('closedAt')}: {dayjs(incident.closedAt).format("LLL")} -
} + {incident.closedAt && ( +
+ {t("closedAt")}: + {dayjs(incident.closedAt).format("LLL")} +
+ )}
@@ -116,16 +116,13 @@ function IncidentCard(props: { incident: Incident, closeIncident: any }) { - {t('enter')} + {t("enter")} - {incident.closedAt === null ? ( ) : ( )}
- ) + ); } export default List; diff --git a/ui/src/views/incident/New.tsx b/ui/src/views/incident/New.tsx index e904a5ef..c81a042d 100644 --- a/ui/src/views/incident/New.tsx +++ b/ui/src/views/incident/New.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/anchor-is-valid */ -/* eslint-disable jsx-a11y/anchor-has-content */ import { useMutation } from "@apollo/client"; import { faClipboard, faLocationDot } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; diff --git a/ui/src/views/journal/Editor.tsx b/ui/src/views/journal/Editor.tsx index 38603dda..2e2c9db4 100644 --- a/ui/src/views/journal/Editor.tsx +++ b/ui/src/views/journal/Editor.tsx @@ -138,20 +138,26 @@ function Editor() { return Object.assign({}, state, { time: action.time }); } case "set_media_detail": { - switch (action.detail.type) { + const details = { + sender: state.senderDetail, + receiver: state.receiverDetail, + ...action.detail, + }; + + switch (details.type) { case Medium.Radio: - return Object.assign({}, state, { media: action.detail.type, radioChannel: action.detail.channel }); + return { + ...state, + media: details.type, + radioChannel: details.channel || "", + }; default: - const details = Object.assign( - {}, - { sender: state.senderDetail, receiver: state.receiverDetail }, - action.detail, - ); - return Object.assign({}, state, { - media: action.detail.type, + return { + ...state, + media: details.type, senderDetail: details.sender, receiverDetail: details.receiver, - }); + }; } } case "clear": { diff --git a/ui/src/views/journal/EditorForms/Elements.tsx b/ui/src/views/journal/EditorForms/Elements.tsx index 50c7ac0b..9f98a9a6 100644 --- a/ui/src/views/journal/EditorForms/Elements.tsx +++ b/ui/src/views/journal/EditorForms/Elements.tsx @@ -6,184 +6,186 @@ import { Hint } from "react-autocomplete-hint"; import { Medium } from "types"; import { useEditorContext } from "../Editor"; - const SenderInput = () => { - const { state, dispatch } = useEditorContext(); - - return ( -
- - { - e.preventDefault(); - dispatch({ type: 'set_sender', sender: e.target.value }); - }} - /> - - - - -
- ) -} + const { state, dispatch } = useEditorContext(); + + return ( +
+ + { + e.preventDefault(); + dispatch({ type: "set_sender", sender: e.target.value }); + }} + /> + + + + +
+ ); +}; const ReceiverInput = () => { - const { state, dispatch } = useEditorContext(); - - return ( -
- - { - e.preventDefault(); - dispatch({ type: 'set_receiver', receiver: e.target.value }); - }} - /> - - - - -
- ) -} + const { state, dispatch } = useEditorContext(); + + return ( +
+ + { + e.preventDefault(); + dispatch({ type: "set_receiver", receiver: e.target.value }); + }} + /> + + + + +
+ ); +}; const ContentInput = () => { - const { state, dispatch } = useEditorContext(); - return ( - - -
-