mirror of
https://github.com/pawelmalak/flame.git
synced 2024-12-18 23:41:39 +03:00
Added search tab to settings
This commit is contained in:
parent
6a6f1750b1
commit
1d8e36b46d
@ -13,7 +13,6 @@ import {
|
||||
import {
|
||||
GlobalState,
|
||||
NewNotification,
|
||||
Query,
|
||||
SettingsForm,
|
||||
} from '../../../interfaces';
|
||||
|
||||
@ -26,7 +25,6 @@ import classes from './OtherSettings.module.css';
|
||||
|
||||
// Utils
|
||||
import { searchConfig } from '../../../utility';
|
||||
import { queries } from '../../../utility/searchQueries.json';
|
||||
|
||||
interface ComponentProps {
|
||||
createNotification: (notification: NewNotification) => void;
|
||||
@ -45,15 +43,12 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
|
||||
hideHeader: 0,
|
||||
hideApps: 0,
|
||||
hideCategories: 0,
|
||||
hideSearch: 0,
|
||||
defaultSearchProvider: 'd',
|
||||
useOrdering: 'createdAt',
|
||||
appsSameTab: 0,
|
||||
bookmarksSameTab: 0,
|
||||
searchSameTab: 0,
|
||||
dockerApps: 1,
|
||||
kubernetesApps: 1,
|
||||
unpinStoppedApps: 1,
|
||||
dockerApps: 0,
|
||||
kubernetesApps: 0,
|
||||
unpinStoppedApps: 0,
|
||||
});
|
||||
|
||||
// Get config
|
||||
@ -65,12 +60,9 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
|
||||
hideHeader: searchConfig('hideHeader', 0),
|
||||
hideApps: searchConfig('hideApps', 0),
|
||||
hideCategories: searchConfig('hideCategories', 0),
|
||||
hideSearch: searchConfig('hideSearch', 0),
|
||||
defaultSearchProvider: searchConfig('defaultSearchProvider', 'd'),
|
||||
useOrdering: searchConfig('useOrdering', 'createdAt'),
|
||||
appsSameTab: searchConfig('appsSameTab', 0),
|
||||
bookmarksSameTab: searchConfig('bookmarksSameTab', 0),
|
||||
searchSameTab: searchConfig('searchSameTab', 0),
|
||||
dockerApps: searchConfig('dockerApps', 0),
|
||||
kubernetesApps: searchConfig('kubernetesApps', 0),
|
||||
unpinStoppedApps: searchConfig('unpinStoppedApps', 0),
|
||||
@ -168,35 +160,6 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
|
||||
<option value="orderId">Custom order</option>
|
||||
</select>
|
||||
</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>
|
||||
<label htmlFor="appsSameTab">Open applications in the same tab</label>
|
||||
<select
|
||||
@ -224,18 +187,6 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
|
||||
|
||||
{/* MODULES OPTIONS */}
|
||||
<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>
|
||||
<label htmlFor="hideHeader">Hide greeting and date</label>
|
||||
<select
|
||||
|
133
client/src/components/Settings/SearchSettings/SearchSettings.tsx
Normal file
133
client/src/components/Settings/SearchSettings/SearchSettings.tsx
Normal 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);
|
@ -1,73 +1,61 @@
|
||||
//
|
||||
import { NavLink, Link, Switch, Route } from 'react-router-dom';
|
||||
|
||||
// Typescript
|
||||
import { Route as SettingsRoute } from '../../interfaces';
|
||||
|
||||
// CSS
|
||||
import classes from './Settings.module.css';
|
||||
|
||||
import { Container } from '../UI/Layout/Layout';
|
||||
import Headline from '../UI/Headlines/Headline/Headline';
|
||||
|
||||
// Components
|
||||
import Themer from '../Themer/Themer';
|
||||
import WeatherSettings from './WeatherSettings/WeatherSettings';
|
||||
import OtherSettings from './OtherSettings/OtherSettings';
|
||||
import AppDetails from './AppDetails/AppDetails';
|
||||
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 => {
|
||||
return (
|
||||
<Container>
|
||||
<Headline
|
||||
title='Settings'
|
||||
subtitle={<Link to='/'>Go back</Link>}
|
||||
/>
|
||||
<Headline title="Settings" subtitle={<Link to="/">Go back</Link>} />
|
||||
<div className={classes.Settings}>
|
||||
{/* NAVIGATION MENU */}
|
||||
<nav className={classes.SettingsNav}>
|
||||
{routes.map(({ name, dest }: SettingsRoute, idx) => (
|
||||
<NavLink
|
||||
className={classes.SettingsNavLink}
|
||||
activeClassName={classes.SettingsNavLinkActive}
|
||||
exact
|
||||
to='/settings'>
|
||||
Theme
|
||||
</NavLink>
|
||||
<NavLink
|
||||
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
|
||||
to={dest}
|
||||
key={idx}
|
||||
>
|
||||
{name}
|
||||
</NavLink>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
{/* ROUTES */}
|
||||
<section className={classes.SettingsContent}>
|
||||
<Switch>
|
||||
<Route exact path='/settings' component={Themer} />
|
||||
<Route path='/settings/weather' component={WeatherSettings} />
|
||||
<Route path='/settings/other' component={OtherSettings} />
|
||||
<Route path='/settings/css' component={StyleSettings} />
|
||||
<Route path='/settings/app' component={AppDetails} />
|
||||
<Route exact path="/settings" component={Themer} />
|
||||
<Route path="/settings/weather" component={WeatherSettings} />
|
||||
<Route path="/settings/search" component={SearchSettings} />
|
||||
<Route path="/settings/other" component={OtherSettings} />
|
||||
<Route path="/settings/css" component={StyleSettings} />
|
||||
<Route path="/settings/app" component={AppDetails} />
|
||||
</Switch>
|
||||
</section>
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default Settings;
|
28
client/src/components/Settings/settings.json
Normal file
28
client/src/components/Settings/settings.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
@ -5,6 +5,12 @@ export interface WeatherForm {
|
||||
isCelsius: number;
|
||||
}
|
||||
|
||||
export interface SearchForm {
|
||||
hideSearch: number;
|
||||
defaultSearchProvider: string;
|
||||
searchSameTab: number;
|
||||
}
|
||||
|
||||
export interface SettingsForm {
|
||||
customTitle: string;
|
||||
pinAppsByDefault: number;
|
||||
@ -12,12 +18,12 @@ export interface SettingsForm {
|
||||
hideHeader: number;
|
||||
hideApps: number;
|
||||
hideCategories: number;
|
||||
hideSearch: number;
|
||||
defaultSearchProvider: string;
|
||||
// hideSearch: number;
|
||||
// defaultSearchProvider: string;
|
||||
useOrdering: string;
|
||||
appsSameTab: number;
|
||||
bookmarksSameTab: number;
|
||||
searchSameTab: number;
|
||||
// searchSameTab: number;
|
||||
dockerApps: number;
|
||||
kubernetesApps: number;
|
||||
unpinStoppedApps: number;
|
||||
|
4
client/src/interfaces/Route.ts
Normal file
4
client/src/interfaces/Route.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export interface Route {
|
||||
name: string;
|
||||
dest: string;
|
||||
}
|
@ -10,3 +10,4 @@ export * from './Config';
|
||||
export * from './Forms';
|
||||
export * from './Query';
|
||||
export * from './SearchResult';
|
||||
export * from './Route';
|
||||
|
Loading…
Reference in New Issue
Block a user