Added search tab to settings

This commit is contained in:
unknown 2021-10-04 17:07:02 +02:00
parent 6a6f1750b1
commit 1d8e36b46d
7 changed files with 216 additions and 105 deletions

View File

@ -13,7 +13,6 @@ import {
import { import {
GlobalState, GlobalState,
NewNotification, NewNotification,
Query,
SettingsForm, SettingsForm,
} from '../../../interfaces'; } from '../../../interfaces';
@ -26,7 +25,6 @@ import classes from './OtherSettings.module.css';
// Utils // Utils
import { searchConfig } from '../../../utility'; import { searchConfig } from '../../../utility';
import { queries } from '../../../utility/searchQueries.json';
interface ComponentProps { interface ComponentProps {
createNotification: (notification: NewNotification) => void; createNotification: (notification: NewNotification) => void;
@ -45,15 +43,12 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
hideHeader: 0, hideHeader: 0,
hideApps: 0, hideApps: 0,
hideCategories: 0, hideCategories: 0,
hideSearch: 0,
defaultSearchProvider: 'd',
useOrdering: 'createdAt', useOrdering: 'createdAt',
appsSameTab: 0, appsSameTab: 0,
bookmarksSameTab: 0, bookmarksSameTab: 0,
searchSameTab: 0, dockerApps: 0,
dockerApps: 1, kubernetesApps: 0,
kubernetesApps: 1, unpinStoppedApps: 0,
unpinStoppedApps: 1,
}); });
// Get config // Get config
@ -65,12 +60,9 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
hideHeader: searchConfig('hideHeader', 0), hideHeader: searchConfig('hideHeader', 0),
hideApps: searchConfig('hideApps', 0), hideApps: searchConfig('hideApps', 0),
hideCategories: searchConfig('hideCategories', 0), hideCategories: searchConfig('hideCategories', 0),
hideSearch: searchConfig('hideSearch', 0),
defaultSearchProvider: searchConfig('defaultSearchProvider', 'd'),
useOrdering: searchConfig('useOrdering', 'createdAt'), useOrdering: searchConfig('useOrdering', 'createdAt'),
appsSameTab: searchConfig('appsSameTab', 0), appsSameTab: searchConfig('appsSameTab', 0),
bookmarksSameTab: searchConfig('bookmarksSameTab', 0), bookmarksSameTab: searchConfig('bookmarksSameTab', 0),
searchSameTab: searchConfig('searchSameTab', 0),
dockerApps: searchConfig('dockerApps', 0), dockerApps: searchConfig('dockerApps', 0),
kubernetesApps: searchConfig('kubernetesApps', 0), kubernetesApps: searchConfig('kubernetesApps', 0),
unpinStoppedApps: searchConfig('unpinStoppedApps', 0), unpinStoppedApps: searchConfig('unpinStoppedApps', 0),
@ -168,35 +160,6 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
<option value="orderId">Custom order</option> <option value="orderId">Custom order</option>
</select> </select>
</InputGroup> </InputGroup>
<InputGroup>
<label htmlFor="defaultSearchProvider">Default Search Provider</label>
<select
id="defaultSearchProvider"
name="defaultSearchProvider"
value={formData.defaultSearchProvider}
onChange={(e) => inputChangeHandler(e)}
>
{queries.map((query: Query, idx) => (
<option key={idx} value={query.prefix}>
{query.name}
</option>
))}
</select>
</InputGroup>
<InputGroup>
<label htmlFor="searchSameTab">
Open search results in the same tab
</label>
<select
id="searchSameTab"
name="searchSameTab"
value={formData.searchSameTab}
onChange={(e) => inputChangeHandler(e, true)}
>
<option value={1}>True</option>
<option value={0}>False</option>
</select>
</InputGroup>
<InputGroup> <InputGroup>
<label htmlFor="appsSameTab">Open applications in the same tab</label> <label htmlFor="appsSameTab">Open applications in the same tab</label>
<select <select
@ -224,18 +187,6 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
{/* MODULES OPTIONS */} {/* MODULES OPTIONS */}
<h2 className={classes.SettingsSection}>Modules</h2> <h2 className={classes.SettingsSection}>Modules</h2>
<InputGroup>
<label htmlFor="hideSearch">Hide search bar</label>
<select
id="hideSearch"
name="hideSearch"
value={formData.hideSearch}
onChange={(e) => inputChangeHandler(e, true)}
>
<option value={1}>True</option>
<option value={0}>False</option>
</select>
</InputGroup>
<InputGroup> <InputGroup>
<label htmlFor="hideHeader">Hide greeting and date</label> <label htmlFor="hideHeader">Hide greeting and date</label>
<select <select

View File

@ -0,0 +1,133 @@
// React
import { useState, useEffect, FormEvent, ChangeEvent } from 'react';
import { connect } from 'react-redux';
// State
import { createNotification, updateConfig } from '../../../store/actions';
// Typescript
import {
GlobalState,
NewNotification,
Query,
SearchForm,
} from '../../../interfaces';
// Utils
import { searchConfig } from '../../../utility';
import InputGroup from '../../UI/Forms/InputGroup/InputGroup';
// Data
import { queries } from '../../../utility/searchQueries.json';
// UI
import Button from '../../UI/Buttons/Button/Button';
interface Props {
createNotification: (notification: NewNotification) => void;
updateConfig: (formData: SearchForm) => void;
loading: boolean;
}
const SearchSettings = (props: Props): JSX.Element => {
// Initial state
const [formData, setFormData] = useState<SearchForm>({
hideSearch: 0,
defaultSearchProvider: 'l',
searchSameTab: 0,
});
// Get config
useEffect(() => {
setFormData({
hideSearch: searchConfig('hideSearch', 0),
defaultSearchProvider: searchConfig('defaultSearchProvider', 'd'),
searchSameTab: searchConfig('searchSameTab', 0),
});
}, [props.loading]);
// Form handler
const formSubmitHandler = async (e: FormEvent) => {
e.preventDefault();
// Save settings
await props.updateConfig(formData);
};
// Input handler
const inputChangeHandler = (
e: ChangeEvent<HTMLInputElement | HTMLSelectElement>,
isNumber?: boolean
) => {
let value: string | number = e.target.value;
if (isNumber) {
value = parseFloat(value);
}
setFormData({
...formData,
[e.target.name]: value,
});
};
return (
<form onSubmit={(e) => formSubmitHandler(e)}>
<InputGroup>
<label htmlFor="defaultSearchProvider">Default Search Provider</label>
<select
id="defaultSearchProvider"
name="defaultSearchProvider"
value={formData.defaultSearchProvider}
onChange={(e) => inputChangeHandler(e)}
>
{queries.map((query: Query, idx) => (
<option key={idx} value={query.prefix}>
{query.name}
</option>
))}
</select>
</InputGroup>
<InputGroup>
<label htmlFor="searchSameTab">
Open search results in the same tab
</label>
<select
id="searchSameTab"
name="searchSameTab"
value={formData.searchSameTab}
onChange={(e) => inputChangeHandler(e, true)}
>
<option value={1}>True</option>
<option value={0}>False</option>
</select>
</InputGroup>
<InputGroup>
<label htmlFor="hideSearch">Hide search bar</label>
<select
id="hideSearch"
name="hideSearch"
value={formData.hideSearch}
onChange={(e) => inputChangeHandler(e, true)}
>
<option value={1}>True</option>
<option value={0}>False</option>
</select>
</InputGroup>
<Button>Save changes</Button>
</form>
);
};
const mapStateToProps = (state: GlobalState) => {
return {
loading: state.config.loading,
};
};
const actions = {
createNotification,
updateConfig,
};
export default connect(mapStateToProps, actions)(SearchSettings);

View File

@ -1,73 +1,61 @@
//
import { NavLink, Link, Switch, Route } from 'react-router-dom'; import { NavLink, Link, Switch, Route } from 'react-router-dom';
// Typescript
import { Route as SettingsRoute } from '../../interfaces';
// CSS
import classes from './Settings.module.css'; import classes from './Settings.module.css';
import { Container } from '../UI/Layout/Layout'; // Components
import Headline from '../UI/Headlines/Headline/Headline';
import Themer from '../Themer/Themer'; import Themer from '../Themer/Themer';
import WeatherSettings from './WeatherSettings/WeatherSettings'; import WeatherSettings from './WeatherSettings/WeatherSettings';
import OtherSettings from './OtherSettings/OtherSettings'; import OtherSettings from './OtherSettings/OtherSettings';
import AppDetails from './AppDetails/AppDetails'; import AppDetails from './AppDetails/AppDetails';
import StyleSettings from './StyleSettings/StyleSettings'; import StyleSettings from './StyleSettings/StyleSettings';
import SearchSettings from './SearchSettings/SearchSettings';
// UI
import { Container } from '../UI/Layout/Layout';
import Headline from '../UI/Headlines/Headline/Headline';
// Data
import { routes } from './settings.json';
const Settings = (): JSX.Element => { const Settings = (): JSX.Element => {
return ( return (
<Container> <Container>
<Headline <Headline title="Settings" subtitle={<Link to="/">Go back</Link>} />
title='Settings'
subtitle={<Link to='/'>Go back</Link>}
/>
<div className={classes.Settings}> <div className={classes.Settings}>
{/* NAVIGATION MENU */}
<nav className={classes.SettingsNav}> <nav className={classes.SettingsNav}>
{routes.map(({ name, dest }: SettingsRoute, idx) => (
<NavLink <NavLink
className={classes.SettingsNavLink} className={classes.SettingsNavLink}
activeClassName={classes.SettingsNavLinkActive} activeClassName={classes.SettingsNavLinkActive}
exact exact
to='/settings'> to={dest}
Theme key={idx}
</NavLink> >
<NavLink {name}
className={classes.SettingsNavLink}
activeClassName={classes.SettingsNavLinkActive}
exact
to='/settings/weather'>
Weather
</NavLink>
<NavLink
className={classes.SettingsNavLink}
activeClassName={classes.SettingsNavLinkActive}
exact
to='/settings/other'>
Other
</NavLink>
<NavLink
className={classes.SettingsNavLink}
activeClassName={classes.SettingsNavLinkActive}
exact
to='/settings/css'>
CSS
</NavLink>
<NavLink
className={classes.SettingsNavLink}
activeClassName={classes.SettingsNavLinkActive}
exact
to='/settings/app'>
App
</NavLink> </NavLink>
))}
</nav> </nav>
{/* ROUTES */}
<section className={classes.SettingsContent}> <section className={classes.SettingsContent}>
<Switch> <Switch>
<Route exact path='/settings' component={Themer} /> <Route exact path="/settings" component={Themer} />
<Route path='/settings/weather' component={WeatherSettings} /> <Route path="/settings/weather" component={WeatherSettings} />
<Route path='/settings/other' component={OtherSettings} /> <Route path="/settings/search" component={SearchSettings} />
<Route path='/settings/css' component={StyleSettings} /> <Route path="/settings/other" component={OtherSettings} />
<Route path='/settings/app' component={AppDetails} /> <Route path="/settings/css" component={StyleSettings} />
<Route path="/settings/app" component={AppDetails} />
</Switch> </Switch>
</section> </section>
</div> </div>
</Container> </Container>
) );
} };
export default Settings; export default Settings;

View File

@ -0,0 +1,28 @@
{
"routes": [
{
"name": "Theme",
"dest": "/settings"
},
{
"name": "Weather",
"dest": "/settings/weather"
},
{
"name": "Search",
"dest": "/settings/search"
},
{
"name": "Other",
"dest": "/settings/other"
},
{
"name": "CSS",
"dest": "/settings/css"
},
{
"name": "App",
"dest": "/settings/app"
}
]
}

View File

@ -5,6 +5,12 @@ export interface WeatherForm {
isCelsius: number; isCelsius: number;
} }
export interface SearchForm {
hideSearch: number;
defaultSearchProvider: string;
searchSameTab: number;
}
export interface SettingsForm { export interface SettingsForm {
customTitle: string; customTitle: string;
pinAppsByDefault: number; pinAppsByDefault: number;
@ -12,12 +18,12 @@ export interface SettingsForm {
hideHeader: number; hideHeader: number;
hideApps: number; hideApps: number;
hideCategories: number; hideCategories: number;
hideSearch: number; // hideSearch: number;
defaultSearchProvider: string; // defaultSearchProvider: string;
useOrdering: string; useOrdering: string;
appsSameTab: number; appsSameTab: number;
bookmarksSameTab: number; bookmarksSameTab: number;
searchSameTab: number; // searchSameTab: number;
dockerApps: number; dockerApps: number;
kubernetesApps: number; kubernetesApps: number;
unpinStoppedApps: number; unpinStoppedApps: number;

View File

@ -0,0 +1,4 @@
export interface Route {
name: string;
dest: string;
}

View File

@ -10,3 +10,4 @@ export * from './Config';
export * from './Forms'; export * from './Forms';
export * from './Query'; export * from './Query';
export * from './SearchResult'; export * from './SearchResult';
export * from './Route';