From df6d96f5b697c8a149a9c5ccba9a5ce70a95918d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Tue, 26 Oct 2021 13:09:42 +0200 Subject: [PATCH 1/4] Added option to disable search bar autofocus --- DEV_GUIDELINES.md | 10 +++++++++ client/src/components/SearchBar/SearchBar.tsx | 21 ++++++++++++++----- .../SearchSettings/SearchSettings.tsx | 12 +++++++++++ client/src/interfaces/Config.ts | 1 + client/src/interfaces/Forms.ts | 1 + .../utility/templateObjects/configTemplate.ts | 1 + .../templateObjects/settingsTemplate.ts | 1 + utils/init/initialConfig.json | 4 +++- 8 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 DEV_GUIDELINES.md diff --git a/DEV_GUIDELINES.md b/DEV_GUIDELINES.md new file mode 100644 index 0000000..462a17f --- /dev/null +++ b/DEV_GUIDELINES.md @@ -0,0 +1,10 @@ +## Adding new config key + +1. Edit utils/init/initialConfig.json +2. Edit client/src/interfaces/Config.ts +3. Edit client/src/utility/templateObjects/configTemplate.ts + +If config value will be used in a form: + +4. Edit client/src/interfaces/Forms.ts +5. Edit client/src/utility/templateObjects/settingsTemplate.ts \ No newline at end of file diff --git a/client/src/components/SearchBar/SearchBar.tsx b/client/src/components/SearchBar/SearchBar.tsx index b6a981f..a535c19 100644 --- a/client/src/components/SearchBar/SearchBar.tsx +++ b/client/src/components/SearchBar/SearchBar.tsx @@ -5,7 +5,7 @@ import { connect } from 'react-redux'; import { createNotification } from '../../store/actions'; // Typescript -import { NewNotification } from '../../interfaces'; +import { Config, GlobalState, NewNotification } from '../../interfaces'; // CSS import classes from './SearchBar.module.css'; @@ -16,16 +16,20 @@ import { searchParser, urlParser, redirectUrl } from '../../utility'; interface ComponentProps { createNotification: (notification: NewNotification) => void; setLocalSearch: (query: string) => void; + config: Config; + loading: boolean; } const SearchBar = (props: ComponentProps): JSX.Element => { - const { setLocalSearch, createNotification } = props; + const { setLocalSearch, createNotification, config, loading } = props; const inputRef = useRef(document.createElement('input')); useEffect(() => { - inputRef.current.focus(); - }, []); + if (!loading && !config.disableAutofocus) { + inputRef.current.focus(); + } + }, [config]); const clearSearch = () => { inputRef.current.value = ''; @@ -78,4 +82,11 @@ const SearchBar = (props: ComponentProps): JSX.Element => { ); }; -export default connect(null, { createNotification })(SearchBar); +const mapStateToProps = (state: GlobalState) => { + return { + config: state.config.config, + loading: state.config.loading, + }; +}; + +export default connect(mapStateToProps, { createNotification })(SearchBar); diff --git a/client/src/components/Settings/SearchSettings/SearchSettings.tsx b/client/src/components/Settings/SearchSettings/SearchSettings.tsx index a403fa6..d05def5 100644 --- a/client/src/components/Settings/SearchSettings/SearchSettings.tsx +++ b/client/src/components/Settings/SearchSettings/SearchSettings.tsx @@ -121,6 +121,18 @@ const SearchSettings = (props: Props): JSX.Element => { + + + + diff --git a/client/src/interfaces/Config.ts b/client/src/interfaces/Config.ts index 1b60ca7..88f1d5c 100644 --- a/client/src/interfaces/Config.ts +++ b/client/src/interfaces/Config.ts @@ -20,4 +20,5 @@ export interface Config { kubernetesApps: boolean; unpinStoppedApps: boolean; useAmericanDate: boolean; + disableAutofocus: boolean; } diff --git a/client/src/interfaces/Forms.ts b/client/src/interfaces/Forms.ts index 411ce90..6e144bb 100644 --- a/client/src/interfaces/Forms.ts +++ b/client/src/interfaces/Forms.ts @@ -9,6 +9,7 @@ export interface SearchForm { hideSearch: boolean; defaultSearchProvider: string; searchSameTab: boolean; + disableAutofocus: boolean; } export interface OtherSettingsForm { diff --git a/client/src/utility/templateObjects/configTemplate.ts b/client/src/utility/templateObjects/configTemplate.ts index 4d4843f..a6f590a 100644 --- a/client/src/utility/templateObjects/configTemplate.ts +++ b/client/src/utility/templateObjects/configTemplate.ts @@ -22,4 +22,5 @@ export const configTemplate: Config = { kubernetesApps: false, unpinStoppedApps: false, useAmericanDate: false, + disableAutofocus: false, }; diff --git a/client/src/utility/templateObjects/settingsTemplate.ts b/client/src/utility/templateObjects/settingsTemplate.ts index 05bc887..30fa871 100644 --- a/client/src/utility/templateObjects/settingsTemplate.ts +++ b/client/src/utility/templateObjects/settingsTemplate.ts @@ -28,4 +28,5 @@ export const searchSettingsTemplate: SearchForm = { hideSearch: false, searchSameTab: false, defaultSearchProvider: 'l', + disableAutofocus: false, }; diff --git a/utils/init/initialConfig.json b/utils/init/initialConfig.json index f6b57a3..11a839a 100644 --- a/utils/init/initialConfig.json +++ b/utils/init/initialConfig.json @@ -18,5 +18,7 @@ "dockerApps": false, "dockerHost": "localhost", "kubernetesApps": false, - "unpinStoppedApps": false + "unpinStoppedApps": false, + "useAmericanDate": false, + "disableAutofocus": false } From 3d3e2eed8c679a0a88cac349a58dd31cc3f7bd7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Tue, 26 Oct 2021 14:37:01 +0200 Subject: [PATCH 2/4] Fixed bug with weather logging. Fixed bug with search bar shortcuts --- CHANGELOG.md | 5 +++ client/src/components/SearchBar/SearchBar.tsx | 16 +++++++++ utils/getExternalWeather.js | 8 ----- utils/jobs.js | 35 +++++++++++++------ 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc2dbd5..0f57ca1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +### v1.7.2 (TBA) +- Use search bar shortcuts when it's not focused ([#124](https://github.com/pawelmalak/flame/issues/124)) +- Fixed bug with Weather API still logging with module being disabled ([#125](https://github.com/pawelmalak/flame/issues/125)) +- Added option to disable search bar autofocus ([#127](https://github.com/pawelmalak/flame/issues/127)) + ### v1.7.1 (2021-10-22) - Fixed search action not being triggered by Numpad Enter - Added option to change date formatting ([#92](https://github.com/pawelmalak/flame/issues/92)) diff --git a/client/src/components/SearchBar/SearchBar.tsx b/client/src/components/SearchBar/SearchBar.tsx index a535c19..c20b457 100644 --- a/client/src/components/SearchBar/SearchBar.tsx +++ b/client/src/components/SearchBar/SearchBar.tsx @@ -25,12 +25,28 @@ const SearchBar = (props: ComponentProps): JSX.Element => { const inputRef = useRef(document.createElement('input')); + // Search bar autofocus useEffect(() => { if (!loading && !config.disableAutofocus) { inputRef.current.focus(); } }, [config]); + // Listen for keyboard events outside of search bar + useEffect(() => { + const keyOutsideFocus = (e: any) => { + const { key } = e as KeyboardEvent; + + if (key === 'Escape') { + clearSearch(); + } + }; + + window.addEventListener('keydown', keyOutsideFocus); + + return () => window.removeEventListener('keydown', keyOutsideFocus); + }, []); + const clearSearch = () => { inputRef.current.value = ''; setLocalSearch(''); diff --git a/utils/getExternalWeather.js b/utils/getExternalWeather.js index 8b2be8d..20edac4 100644 --- a/utils/getExternalWeather.js +++ b/utils/getExternalWeather.js @@ -5,14 +5,6 @@ const loadConfig = require('./loadConfig'); const getExternalWeather = async () => { const { WEATHER_API_KEY: secret, lat, long } = await loadConfig(); - if (!secret) { - throw new Error('API key was not found. Weather updated failed'); - } - - if (!lat || !long) { - throw new Error('Location was not found. Weather updated failed'); - } - // Fetch data from external API try { const res = await axios.get( diff --git a/utils/jobs.js b/utils/jobs.js index 935f497..9716af0 100644 --- a/utils/jobs.js +++ b/utils/jobs.js @@ -3,20 +3,33 @@ const getExternalWeather = require('./getExternalWeather'); const clearWeatherData = require('./clearWeatherData'); const Sockets = require('../Sockets'); const Logger = require('./Logger'); +const loadConfig = require('./loadConfig'); const logger = new Logger(); // Update weather data every 15 minutes -const weatherJob = schedule.scheduleJob('updateWeather', '0 */15 * * * *', async () => { - try { - const weatherData = await getExternalWeather(); - logger.log('Weather updated'); - Sockets.getSocket('weather').socket.send(JSON.stringify(weatherData)); - } catch (err) { - logger.log(err.message, 'ERROR'); +const weatherJob = schedule.scheduleJob( + 'updateWeather', + '0 */15 * * * *', + async () => { + const { WEATHER_API_KEY: secret } = await loadConfig(); + + try { + const weatherData = await getExternalWeather(); + logger.log('Weather updated'); + Sockets.getSocket('weather').socket.send(JSON.stringify(weatherData)); + } catch (err) { + if (secret) { + logger.log(err.message, 'ERROR'); + } + } } -}) +); // Clear old weather data every 4 hours -const weatherCleanerJob = schedule.scheduleJob('clearWeather', '0 5 */4 * * *', async () => { - clearWeatherData(); -}) \ No newline at end of file +const weatherCleanerJob = schedule.scheduleJob( + 'clearWeather', + '0 5 */4 * * *', + async () => { + clearWeatherData(); + } +); From da13ca6092c2e41b77138654f1f87fe089a92842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Wed, 27 Oct 2021 11:52:57 +0200 Subject: [PATCH 3/4] Search bar redirect to local search results --- CHANGELOG.md | 1 + client/src/components/Home/Home.tsx | 55 ++++++++++++------- client/src/components/SearchBar/SearchBar.tsx | 27 +++++++-- client/src/utility/redirectUrl.ts | 8 ++- 4 files changed, 66 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f57ca1..3eae525 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ### v1.7.2 (TBA) +- Pressing Enter while search bar is focused will now redirect to first result of local search ([#121](https://github.com/pawelmalak/flame/issues/121)) - Use search bar shortcuts when it's not focused ([#124](https://github.com/pawelmalak/flame/issues/124)) - Fixed bug with Weather API still logging with module being disabled ([#125](https://github.com/pawelmalak/flame/issues/125)) - Added option to disable search bar autofocus ([#127](https://github.com/pawelmalak/flame/issues/127)) diff --git a/client/src/components/Home/Home.tsx b/client/src/components/Home/Home.tsx index 18d81bc..4a0adbe 100644 --- a/client/src/components/Home/Home.tsx +++ b/client/src/components/Home/Home.tsx @@ -55,17 +55,21 @@ const Home = (props: ComponentProps): JSX.Element => { // Local search query const [localSearch, setLocalSearch] = useState(null); + const [appSearchResult, setAppSearchResult] = useState(null); + const [bookmarkSearchResult, setBookmarkSearchResult] = useState< + null | Category[] + >(null); // Load applications useEffect(() => { - if (apps.length === 0) { + if (!apps.length) { getApps(); } }, [getApps]); // Load bookmark categories useEffect(() => { - if (categories.length === 0) { + if (!categories.length) { getCategories(); } }, [getCategories]); @@ -87,22 +91,37 @@ const Home = (props: ComponentProps): JSX.Element => { return () => clearInterval(interval); }, []); - // Search bookmarks - const searchBookmarks = (query: string): Category[] => { - const category = { ...categories[0] }; - category.name = 'Search Results'; - category.bookmarks = categories - .map(({ bookmarks }) => bookmarks) - .flat() - .filter(({ name }) => new RegExp(query, 'i').test(name)); + useEffect(() => { + if (localSearch) { + // Search through apps + setAppSearchResult([ + ...apps.filter(({ name }) => new RegExp(localSearch, 'i').test(name)), + ]); - return [category]; - }; + // Search through bookmarks + const category = { ...categories[0] }; + + category.name = 'Search Results'; + category.bookmarks = categories + .map(({ bookmarks }) => bookmarks) + .flat() + .filter(({ name }) => new RegExp(localSearch, 'i').test(name)); + + setBookmarkSearchResult([category]); + } else { + setAppSearchResult(null); + setBookmarkSearchResult(null); + } + }, [localSearch]); return ( {!props.config.hideSearch ? ( - + ) : (
)} @@ -130,11 +149,9 @@ const Home = (props: ComponentProps): JSX.Element => { ) : ( isPinned) - : apps.filter(({ name }) => - new RegExp(localSearch, 'i').test(name) - ) + : appSearchResult } totalApps={apps.length} searching={!!localSearch} @@ -154,9 +171,9 @@ const Home = (props: ComponentProps): JSX.Element => { ) : ( isPinned) - : searchBookmarks(localSearch) + : bookmarkSearchResult } totalCategories={categories.length} searching={!!localSearch} diff --git a/client/src/components/SearchBar/SearchBar.tsx b/client/src/components/SearchBar/SearchBar.tsx index c20b457..7a91525 100644 --- a/client/src/components/SearchBar/SearchBar.tsx +++ b/client/src/components/SearchBar/SearchBar.tsx @@ -5,7 +5,13 @@ import { connect } from 'react-redux'; import { createNotification } from '../../store/actions'; // Typescript -import { Config, GlobalState, NewNotification } from '../../interfaces'; +import { + App, + Category, + Config, + GlobalState, + NewNotification, +} from '../../interfaces'; // CSS import classes from './SearchBar.module.css'; @@ -16,12 +22,21 @@ import { searchParser, urlParser, redirectUrl } from '../../utility'; interface ComponentProps { createNotification: (notification: NewNotification) => void; setLocalSearch: (query: string) => void; + appSearchResult: App[] | null; + bookmarkSearchResult: Category[] | null; config: Config; loading: boolean; } const SearchBar = (props: ComponentProps): JSX.Element => { - const { setLocalSearch, createNotification, config, loading } = props; + const { + setLocalSearch, + createNotification, + config, + loading, + appSearchResult, + bookmarkSearchResult, + } = props; const inputRef = useRef(document.createElement('input')); @@ -73,8 +88,12 @@ const SearchBar = (props: ComponentProps): JSX.Element => { const url = urlParser(inputRef.current.value)[1]; redirectUrl(url, sameTab); } else if (isLocal) { - // Local query -> filter apps and bookmarks - setLocalSearch(search); + // Local query -> redirect if at least 1 result found + if (appSearchResult?.length) { + redirectUrl(appSearchResult[0].url, sameTab); + } else if (bookmarkSearchResult?.length) { + redirectUrl(bookmarkSearchResult[0].bookmarks[0].url, sameTab); + } } else { // Valid query -> redirect to search results const url = `${query.template}${search}`; diff --git a/client/src/utility/redirectUrl.ts b/client/src/utility/redirectUrl.ts index 81eca10..533f5d2 100644 --- a/client/src/utility/redirectUrl.ts +++ b/client/src/utility/redirectUrl.ts @@ -1,7 +1,11 @@ +import { urlParser } from '.'; + export const redirectUrl = (url: string, sameTab: boolean) => { + const parsedUrl = urlParser(url)[1]; + if (sameTab) { - document.location.replace(url); + document.location.replace(parsedUrl); } else { - window.open(url); + window.open(parsedUrl); } }; From feb7275cf8648d99b1d2aa1e27ae050cb53285a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Thu, 28 Oct 2021 11:44:36 +0200 Subject: [PATCH 4/4] Pushed version 1.7.2 --- .env | 2 +- CHANGELOG.md | 2 +- client/.env | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.env b/.env index e2c26fc..3288f33 100644 --- a/.env +++ b/.env @@ -1,3 +1,3 @@ PORT=5005 NODE_ENV=development -VERSION=1.7.1 \ No newline at end of file +VERSION=1.7.2 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eae525..25d796b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### v1.7.2 (TBA) +### v1.7.2 (2021-10-28) - Pressing Enter while search bar is focused will now redirect to first result of local search ([#121](https://github.com/pawelmalak/flame/issues/121)) - Use search bar shortcuts when it's not focused ([#124](https://github.com/pawelmalak/flame/issues/124)) - Fixed bug with Weather API still logging with module being disabled ([#125](https://github.com/pawelmalak/flame/issues/125)) diff --git a/client/.env b/client/.env index 1511942..e16ddf3 100644 --- a/client/.env +++ b/client/.env @@ -1 +1 @@ -REACT_APP_VERSION=1.7.1 \ No newline at end of file +REACT_APP_VERSION=1.7.2 \ No newline at end of file