From e141aa15e5ac1154936aae2cb0990a6f53051563 Mon Sep 17 00:00:00 2001 From: Adrien Date: Sat, 28 Jan 2023 16:18:55 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=9A=20Remove=20business=20logic=20from?= =?UTF-8?q?=20Component=20instances?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/businessData.tsx | 53 ++++++++++++++-------- frontend/src/passagesDisplay.tsx | 65 ++++++--------------------- frontend/src/search.tsx | 75 +++++++++++++------------------- frontend/src/stopsManager.tsx | 40 +++++------------ 4 files changed, 91 insertions(+), 142 deletions(-) diff --git a/frontend/src/businessData.tsx b/frontend/src/businessData.tsx index 8e6e617..7f8eec1 100644 --- a/frontend/src/businessData.tsx +++ b/frontend/src/businessData.tsx @@ -35,44 +35,59 @@ export function BusinessDataProvider(props: { children: JSX.Element }) { return line; } - const passages = () => { - return store.passages; - }; - const getLinePassages = (lineId: string) => { return store.passages[lineId]; }; + const passages = () => { + return store.passages; + } + + const refreshPassages = async (stopId: number) => { + const httpOptions = { headers: { "Content-Type": "application/json" } }; + console.log(`Fetching data for ${stopId}`); + const data = await fetch(`${serverUrl()}/stop/nextPassages/${stopId}`, httpOptions); + const response = await data.json(); + addPassages(response.passages); + } + const addPassages = (passages) => { setStore((s) => { - // console.log("s=", s); setStore('passages', passages); - // console.log("s=", s); }); } const clearPassages = () => { setStore((s) => { - // TODO: Really need to set to undefined to reset ? - console.log("s=", s); - console.log("s.passages=", s.passages); - // setStore('passages', undefined); - // setStore('passages', {}); - console.log("Object.keys(s.passages)=", Object.keys(s.passages)); for (const lineId of Object.keys(s.passages)) { - console.log("lineId=", lineId); setStore('passages', lineId, undefined); } - console.log("s=", s); }); - // setStore('passages', undefined); - // setStore('passages', {}); - // } - console.log("passages=", store.passages); + } + + const getStop = (stopId: int) => { + return store.stops[stopId]; + } + + const searchStopByName = async (name: string) => { + const data = await fetch(`${serverUrl()}/stop/?name=${name}`, { + headers: { 'Content-Type': 'application/json' } + }); + const stops = await data.json(); + + const byIdStops = {}; + for (const stop of stops) { + byIdStops[stop.id] = stop; + setStore('stops', stop.id, stop); + } + return byIdStops; } return ( - + {props.children} ); diff --git a/frontend/src/passagesDisplay.tsx b/frontend/src/passagesDisplay.tsx index bc03a34..9882623 100644 --- a/frontend/src/passagesDisplay.tsx +++ b/frontend/src/passagesDisplay.tsx @@ -16,13 +16,13 @@ export const PassagesDisplay: Component = () => { const maxPassagePerPanel = 5; const syncPeriodMsec = 20 * 1000; - const { passages, getLinePassages, addPassages, clearPassages, serverUrl } = useContext(BusinessDataContext); - const { getDisplayedStop } = useContext(SearchContext); + const { passages, getLine, getLinePassages, refreshPassages, clearPassages } = useContext(BusinessDataContext); + + // TODO: Use props instead + const { getDisplayedStops } = useContext(SearchContext); - const [panels, setPanels] = createStore([]); const [displayedPanelId, setDisplayedPanelId] = createSignal(0); - - let _lines = new Map(); + const [panels, setPanels] = createStore([]); const [dateNow] = createDateNow(1000); @@ -37,61 +37,24 @@ export const PassagesDisplay: Component = () => { createEffect(() => { console.log("######### onStopIdUpdate #########"); // Track local.stopIp to force dependency. - console.log("getDisplayedStop=", getDisplayedStop()); + console.log("getDisplayedStop=", getDisplayedStops()); clearPassages(); }); createEffect(async () => { console.log(`## OnPassageUpdate ${passages()} ##`); - /* console.log(passages()); */ - await requestPassages(); + const stops = getDisplayedStops(); + if (stops.length > 0) { + refreshPassages(stops[0].id); + } }); - async function _fetchLine(lineId: string) { - if (!_lines.has(lineId)) { - const data = await fetch(`${serverUrl()}/line/${lineId}`, { - headers: { "Content-Type": "application/json" }, - }); - const line = await data.json(); - _lines.set(line.id, line); - } - } - - async function requestPassages() { - console.log("### requestPassages ###"); - /* TODO: Manage several displays (one by stop) */ - const stops = getDisplayedStop(); - if (stops.length == 0) { - return; - } - const stop = stops[0]; - - const httpOptions = { headers: { "Content-Type": "application/json" } }; - if (stop !== undefined) { - const stopId = stop.id; - console.log(`Fetching data for ${stopId}`); - const url = `${serverUrl()}/stop/nextPassages/${stopId}`; - /* console.log(`url=${url}`); */ - const data = await fetch(url, httpOptions); - const response = await data.json(); - /* console.log(response); */ - const byLineByDstPassages = response.passages; - /* console.log(byLineByDstPassages); */ - const linePromises = []; - for (const lineId of Object.keys(byLineByDstPassages)) { - linePromises.push(_fetchLine(lineId)); - } - await Promise.all(linePromises); - console.log("byLineByDstPassages=", byLineByDstPassages); - // console.log("before addPassages passages=", passages()); - addPassages(byLineByDstPassages); - console.log("AFTER passages=", passages()); - } - } - setInterval( async () => { - await requestPassages(); + const stops = getDisplayedStops(); + if (stops.length > 0) { + refreshPassages(stops[0].id); + } }, syncPeriodMsec ); diff --git a/frontend/src/search.tsx b/frontend/src/search.tsx index c9e2163..02c73d6 100644 --- a/frontend/src/search.tsx +++ b/frontend/src/search.tsx @@ -21,55 +21,42 @@ export const SearchContext = createContext(); export function SearchProvider(props: { children: JSX.Element }) { - const [store, setStore] = createStore({stops: {}, markers: {}, displayedStop: []}); + const [store, setStore] = createStore({ stops: {}, markers: {}, displayedStops: [] }); - const getStops = () => { - return store.stops; - }; + const getDisplayedStops = () => { + return store.displayedStops; + } - const setStops = (stops) => { - setStore((s) => { - setStore('stops', stops); - }); - }; + const setDisplayedStops = (stops: Array) => { + setStore((s) => { + setStore('displayedStops', stops); + }); + } - const removeStops = (stopIds) => { - batch(() => { - for(const stopId of stopIds) { - setStore('stops', stopId, undefined); - setStore('markers', stopId, undefined); - } - }); - }; + const removeStops = (stopIds: Array) => { + batch(() => { + for (const stopId of stopIds) { + setStore('stops', stopId, undefined); + setStore('markers', stopId, undefined); + } + }); + } - const getMarkers = () => { - return store.markers; - }; + const getMarkers = () => { + return store.markers; + } - const addMarkers = (stopId, markers) => { - setStore('markers', stopId, markers); - }; + const addMarkers = (stopId: number, markers) => { + setStore('markers', stopId, markers); + } - const setMarkers = (markers) => { - setStore('markers', markers); - }; + const setMarkers = (markers) => { + setStore('markers', markers); + } - const getDisplayedStop = () => { - /* console.log(store.displayedStop); */ - return store.displayedStop; - }; - const setDisplayedStop = (stop: Stop) => { - /* console.log(stop); */ - setStore((s) => { - console.log("s.displayedStop=", s.displayedStop); - setStore('displayedStop', [stop]); - }); - /* console.log(store.displayedStop); */ - }; - - return ( - - {props.children} - - ); + return ( + + {props.children} + + ); } diff --git a/frontend/src/stopsManager.tsx b/frontend/src/stopsManager.tsx index db7ee00..f1c8910 100644 --- a/frontend/src/stopsManager.tsx +++ b/frontend/src/stopsManager.tsx @@ -94,7 +94,7 @@ const Map: Component = (props) => { const mapCenter = [48.853, 2.35]; - const { addMarkers, getStops } = useContext(SearchContext); + const { addMarkers } = useContext(SearchContext); let mapDiv: any; let map = null; @@ -147,40 +147,24 @@ const Map: Component = (props) => { export const StopsManager: Component = (props) => { - const [minCharactersNb, setMinCharactersNb] = createSignal(4); - const [_inProgress, _setInProgress] = createSignal(false); +export const StopsManager: Component = () => { - const { serverUrl } = useContext(BusinessDataContext); - const { getStops, removeStops, setStops, setDisplayedStop } = useContext(SearchContext); + const [minCharactersNb, setMinCharactersNb] = createSignal(4); + const [inProgress, setInProgress] = createSignal(false); + const [foundStops, setFoundStops] = createSignal>([]); - async function _fetchStopByName(name) { - const data = await fetch(`${serverUrl()}/stop/?name=${name}`, { - headers: { 'Content-Type': 'application/json' } - }); - const stops = await data.json(); - const stopIds = stops.map((stop) => stop.id); + const { getStop, searchStopByName } = useContext(BusinessDataContext); + const { setDisplayedStops } = useContext(SearchContext); - const stopIdsToRemove = Object.keys(getStops()).filter(stopId => !(stopId in stopIds)); - - const byIdStops = {}; - for (const stop of stops) { - byIdStops[stop.id] = stop; - } - - batch(() => { - removeStops(stopIdsToRemove); - setStops(byIdStops); - }); - } - - async function _onStopNameInput(event) { + const onStopNameInput = async (event) => { /* TODO: Add a tempo before fetching stop for giving time to user to finish his request */ const stopName = event.target.value; if (stopName.length >= minCharactersNb()) { console.log(`Fetching data for ${stopName}`); - _setInProgress(true); - await _fetchStopByName(stopName); - _setInProgress(false); + setInProgress(true); + const stopsById = await searchStopByName(stopName); + setFoundStops(Object.values(stopsById)); + setInProgress(false); } }