From 15719812520ffd90766b7aa413534cf9613e3580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= <pawel999@icloud.com> Date: Wed, 10 Nov 2021 16:45:30 +0100 Subject: [PATCH] Created separate settings for Docker --- .env | 2 +- README.md | 6 +- .../DockerSettings/DockerSettings.tsx | 122 ++++++++++++++++++ .../SearchSettings/SearchSettings.tsx | 2 + client/src/components/Settings/Settings.tsx | 6 +- .../UISettings.tsx} | 68 +--------- .../WeatherSettings/WeatherSettings.tsx | 2 +- client/src/components/Settings/settings.json | 8 +- client/src/interfaces/Forms.ts | 11 +- client/src/store/action-creators/config.ts | 5 +- .../templateObjects/settingsTemplate.ts | 18 ++- 11 files changed, 167 insertions(+), 83 deletions(-) create mode 100644 client/src/components/Settings/DockerSettings/DockerSettings.tsx rename client/src/components/Settings/{OtherSettings/OtherSettings.tsx => UISettings/UISettings.tsx} (80%) diff --git a/.env b/.env index 6ead5e8..230ec44 100644 --- a/.env +++ b/.env @@ -1,5 +1,5 @@ PORT=5005 NODE_ENV=development VERSION=1.7.4 -PASSWORD=flame +PASSWORD=flame_password SECRET=e02eb43d69953658c6d07311d6313f2d4467672cb881f96b29368ba1f3f4da4b \ No newline at end of file diff --git a/README.md b/README.md index 2a30fa9..33e184e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## Description -Flame is self-hosted startpage for your server. Its design is inspired (heavily) by [SUI](https://github.com/jeroenpardon/sui). Flame is very easy to setup and use. With built-in editors it allows you to setup your very own application hub in no time - no file editing necessary. +Flame is self-hosted startpage for your server. Its design is inspired (heavily) by [SUI](https://github.com/jeroenpardon/sui). Flame is very easy to setup and use. With built-in editors, it allows you to setup your very own application hub in no time - no file editing necessary. ## Technology @@ -151,7 +151,7 @@ labels: # - flame.icon=custom to make changes in app. ie: custom icon upload ``` -> "Use Docker API" option must be enabled for this to work. You can find it in Settings > Other > Docker section +> "Use Docker API" option must be enabled for this to work. You can find it in Settings > Docker You can also set up different apps in the same label adding `;` between each one. @@ -199,7 +199,7 @@ metadata: - flame.pawelmalak/icon=icon-name # optional, default is "kubernetes" ``` -> "Use Kubernetes Ingress API" option must be enabled for this to work. You can find it in Settings > Other > Kubernetes section +> "Use Kubernetes Ingress API" option must be enabled for this to work. You can find it in Settings > Docker ### Import HTML Bookmarks (Experimental) diff --git a/client/src/components/Settings/DockerSettings/DockerSettings.tsx b/client/src/components/Settings/DockerSettings/DockerSettings.tsx new file mode 100644 index 0000000..54410d8 --- /dev/null +++ b/client/src/components/Settings/DockerSettings/DockerSettings.tsx @@ -0,0 +1,122 @@ +import { useState, useEffect, ChangeEvent, FormEvent } from 'react'; + +// Redux +import { useDispatch, useSelector } from 'react-redux'; +import { State } from '../../../store/reducers'; +import { bindActionCreators } from 'redux'; +import { actionCreators } from '../../../store'; + +// Typescript +import { DockerSettingsForm } from '../../../interfaces'; + +// UI +import { InputGroup, Button, SettingsHeadline } from '../../UI'; + +// Utils +import { inputHandler, dockerSettingsTemplate } from '../../../utility'; + +export const DockerSettings = (): JSX.Element => { + const { loading, config } = useSelector((state: State) => state.config); + + const dispatch = useDispatch(); + const { updateConfig } = bindActionCreators(actionCreators, dispatch); + + // Initial state + const [formData, setFormData] = useState<DockerSettingsForm>( + dockerSettingsTemplate + ); + + // Get config + useEffect(() => { + setFormData({ + ...config, + }); + }, [loading]); + + // Form handler + const formSubmitHandler = async (e: FormEvent) => { + e.preventDefault(); + + // Save settings + await updateConfig(formData); + }; + + // Input handler + const inputChangeHandler = ( + e: ChangeEvent<HTMLInputElement | HTMLSelectElement>, + options?: { isNumber?: boolean; isBool?: boolean } + ) => { + inputHandler<DockerSettingsForm>({ + e, + options, + setStateHandler: setFormData, + state: formData, + }); + }; + + return ( + <form onSubmit={(e) => formSubmitHandler(e)}> + <SettingsHeadline text="Docker" /> + {/* CUSTOM DOCKER SOCKET HOST */} + <InputGroup> + <label htmlFor="dockerHost">Docker Host</label> + <input + type="text" + id="dockerHost" + name="dockerHost" + placeholder="dockerHost:port" + value={formData.dockerHost} + onChange={(e) => inputChangeHandler(e)} + /> + </InputGroup> + + {/* USE DOCKER API */} + <InputGroup> + <label htmlFor="dockerApps">Use Docker API</label> + <select + id="dockerApps" + name="dockerApps" + value={formData.dockerApps ? 1 : 0} + onChange={(e) => inputChangeHandler(e, { isBool: true })} + > + <option value={1}>True</option> + <option value={0}>False</option> + </select> + </InputGroup> + + {/* UNPIN DOCKER APPS */} + <InputGroup> + <label htmlFor="unpinStoppedApps"> + Unpin stopped containers / other apps + </label> + <select + id="unpinStoppedApps" + name="unpinStoppedApps" + value={formData.unpinStoppedApps ? 1 : 0} + onChange={(e) => inputChangeHandler(e, { isBool: true })} + > + <option value={1}>True</option> + <option value={0}>False</option> + </select> + </InputGroup> + + {/* KUBERNETES SETTINGS */} + <SettingsHeadline text="Kubernetes" /> + {/* USE KUBERNETES */} + <InputGroup> + <label htmlFor="kubernetesApps">Use Kubernetes Ingress API</label> + <select + id="kubernetesApps" + name="kubernetesApps" + value={formData.kubernetesApps ? 1 : 0} + onChange={(e) => inputChangeHandler(e, { isBool: true })} + > + <option value={1}>True</option> + <option value={0}>False</option> + </select> + </InputGroup> + + <Button>Save changes</Button> + </form> + ); +}; diff --git a/client/src/components/Settings/SearchSettings/SearchSettings.tsx b/client/src/components/Settings/SearchSettings/SearchSettings.tsx index 2717b43..1a931df 100644 --- a/client/src/components/Settings/SearchSettings/SearchSettings.tsx +++ b/client/src/components/Settings/SearchSettings/SearchSettings.tsx @@ -16,6 +16,8 @@ import { inputHandler, searchSettingsTemplate } from '../../../utility'; // Data import { queries } from '../../../utility/searchQueries.json'; + +// Redux import { State } from '../../../store/reducers'; import { bindActionCreators } from 'redux'; import { actionCreators } from '../../../store'; diff --git a/client/src/components/Settings/Settings.tsx b/client/src/components/Settings/Settings.tsx index 0c53693..d506b4e 100644 --- a/client/src/components/Settings/Settings.tsx +++ b/client/src/components/Settings/Settings.tsx @@ -9,10 +9,11 @@ import classes from './Settings.module.css'; // Components import { Themer } from '../Themer/Themer'; import { WeatherSettings } from './WeatherSettings/WeatherSettings'; -import { OtherSettings } from './OtherSettings/OtherSettings'; +import { UISettings } from './UISettings/UISettings'; import { AppDetails } from './AppDetails/AppDetails'; import { StyleSettings } from './StyleSettings/StyleSettings'; import { SearchSettings } from './SearchSettings/SearchSettings'; +import { DockerSettings } from './DockerSettings/DockerSettings'; // UI import { Container, Headline } from '../UI'; @@ -46,7 +47,8 @@ export const Settings = (): JSX.Element => { <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/interface" component={UISettings} /> + <Route path="/settings/docker" component={DockerSettings} /> <Route path="/settings/css" component={StyleSettings} /> <Route path="/settings/app" component={AppDetails} /> </Switch> diff --git a/client/src/components/Settings/OtherSettings/OtherSettings.tsx b/client/src/components/Settings/UISettings/UISettings.tsx similarity index 80% rename from client/src/components/Settings/OtherSettings/OtherSettings.tsx rename to client/src/components/Settings/UISettings/UISettings.tsx index 85b9f06..78d8b14 100644 --- a/client/src/components/Settings/OtherSettings/OtherSettings.tsx +++ b/client/src/components/Settings/UISettings/UISettings.tsx @@ -2,6 +2,9 @@ import { useState, useEffect, ChangeEvent, FormEvent } from 'react'; // Redux import { useDispatch, useSelector } from 'react-redux'; +import { State } from '../../../store/reducers'; +import { bindActionCreators } from 'redux'; +import { actionCreators } from '../../../store'; // Typescript import { OtherSettingsForm } from '../../../interfaces'; @@ -11,11 +14,8 @@ import { InputGroup, Button, SettingsHeadline } from '../../UI'; // Utils import { otherSettingsTemplate, inputHandler } from '../../../utility'; -import { State } from '../../../store/reducers'; -import { bindActionCreators } from 'redux'; -import { actionCreators } from '../../../store'; -export const OtherSettings = (): JSX.Element => { +export const UISettings = (): JSX.Element => { const { loading, config } = useSelector((state: State) => state.config); const dispatch = useDispatch(); @@ -277,66 +277,6 @@ export const OtherSettings = (): JSX.Element => { </select> </InputGroup> - {/* DOCKER SETTINGS */} - <SettingsHeadline text="Docker" /> - {/* CUSTOM DOCKER SOCKET HOST */} - <InputGroup> - <label htmlFor="dockerHost">Docker Host</label> - <input - type="text" - id="dockerHost" - name="dockerHost" - placeholder="dockerHost:port" - value={formData.dockerHost} - onChange={(e) => inputChangeHandler(e)} - /> - </InputGroup> - - {/* USE DOCKER API */} - <InputGroup> - <label htmlFor="dockerApps">Use Docker API</label> - <select - id="dockerApps" - name="dockerApps" - value={formData.dockerApps ? 1 : 0} - onChange={(e) => inputChangeHandler(e, { isBool: true })} - > - <option value={1}>True</option> - <option value={0}>False</option> - </select> - </InputGroup> - - {/* UNPIN DOCKER APPS */} - <InputGroup> - <label htmlFor="unpinStoppedApps"> - Unpin stopped containers / other apps - </label> - <select - id="unpinStoppedApps" - name="unpinStoppedApps" - value={formData.unpinStoppedApps ? 1 : 0} - onChange={(e) => inputChangeHandler(e, { isBool: true })} - > - <option value={1}>True</option> - <option value={0}>False</option> - </select> - </InputGroup> - - {/* KUBERNETES SETTINGS */} - <SettingsHeadline text="Kubernetes" /> - {/* USE KUBERNETES */} - <InputGroup> - <label htmlFor="kubernetesApps">Use Kubernetes Ingress API</label> - <select - id="kubernetesApps" - name="kubernetesApps" - value={formData.kubernetesApps ? 1 : 0} - onChange={(e) => inputChangeHandler(e, { isBool: true })} - > - <option value={1}>True</option> - <option value={0}>False</option> - </select> - </InputGroup> <Button>Save changes</Button> </form> ); diff --git a/client/src/components/Settings/WeatherSettings/WeatherSettings.tsx b/client/src/components/Settings/WeatherSettings/WeatherSettings.tsx index d4af837..c587517 100644 --- a/client/src/components/Settings/WeatherSettings/WeatherSettings.tsx +++ b/client/src/components/Settings/WeatherSettings/WeatherSettings.tsx @@ -5,6 +5,7 @@ import axios from 'axios'; import { useDispatch, useSelector } from 'react-redux'; import { bindActionCreators } from 'redux'; import { actionCreators } from '../../../store'; +import { State } from '../../../store/reducers'; // Typescript import { ApiResponse, Weather, WeatherForm } from '../../../interfaces'; @@ -14,7 +15,6 @@ import { InputGroup, Button } from '../../UI'; // Utils import { inputHandler, weatherSettingsTemplate } from '../../../utility'; -import { State } from '../../../store/reducers'; export const WeatherSettings = (): JSX.Element => { const { loading, config } = useSelector((state: State) => state.config); diff --git a/client/src/components/Settings/settings.json b/client/src/components/Settings/settings.json index 3cc24e9..5c3acc1 100644 --- a/client/src/components/Settings/settings.json +++ b/client/src/components/Settings/settings.json @@ -13,8 +13,12 @@ "dest": "/settings/search" }, { - "name": "Other", - "dest": "/settings/other" + "name": "Interface", + "dest": "/settings/interface" + }, + { + "name": "Docker", + "dest": "/settings/docker" }, { "name": "CSS", diff --git a/client/src/interfaces/Forms.ts b/client/src/interfaces/Forms.ts index 66f4136..7272f21 100644 --- a/client/src/interfaces/Forms.ts +++ b/client/src/interfaces/Forms.ts @@ -22,13 +22,16 @@ export interface OtherSettingsForm { useOrdering: string; appsSameTab: boolean; bookmarksSameTab: boolean; - dockerApps: boolean; - dockerHost: string; - kubernetesApps: boolean; - unpinStoppedApps: boolean; useAmericanDate: boolean; greetingsSchema: string; daySchema: string; monthSchema: string; showTime: boolean; } + +export interface DockerSettingsForm { + dockerApps: boolean; + dockerHost: string; + kubernetesApps: boolean; + unpinStoppedApps: boolean; +} diff --git a/client/src/store/action-creators/config.ts b/client/src/store/action-creators/config.ts index 7522ec8..d81a2a2 100644 --- a/client/src/store/action-creators/config.ts +++ b/client/src/store/action-creators/config.ts @@ -11,6 +11,7 @@ import axios from 'axios'; import { ApiResponse, Config, + DockerSettingsForm, OtherSettingsForm, Query, SearchForm, @@ -49,7 +50,9 @@ export const getConfig = () => async (dispatch: Dispatch<GetConfigAction>) => { }; export const updateConfig = - (formData: WeatherForm | OtherSettingsForm | SearchForm) => + ( + formData: WeatherForm | OtherSettingsForm | SearchForm | DockerSettingsForm + ) => async (dispatch: Dispatch<UpdateConfigAction>) => { try { const res = await axios.put<ApiResponse<Config>>('/api/config', formData); diff --git a/client/src/utility/templateObjects/settingsTemplate.ts b/client/src/utility/templateObjects/settingsTemplate.ts index 981ffba..f175318 100644 --- a/client/src/utility/templateObjects/settingsTemplate.ts +++ b/client/src/utility/templateObjects/settingsTemplate.ts @@ -1,4 +1,9 @@ -import { OtherSettingsForm, SearchForm, WeatherForm } from '../../interfaces'; +import { + DockerSettingsForm, + OtherSettingsForm, + SearchForm, + WeatherForm, +} from '../../interfaces'; export const otherSettingsTemplate: OtherSettingsForm = { customTitle: document.title, @@ -10,10 +15,6 @@ export const otherSettingsTemplate: OtherSettingsForm = { useOrdering: 'createdAt', appsSameTab: false, bookmarksSameTab: false, - dockerApps: true, - dockerHost: 'localhost', - kubernetesApps: true, - unpinStoppedApps: true, useAmericanDate: false, greetingsSchema: 'Good evening!;Good afternoon!;Good morning!;Good night!', daySchema: 'Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday', @@ -35,3 +36,10 @@ export const searchSettingsTemplate: SearchForm = { defaultSearchProvider: 'l', disableAutofocus: false, }; + +export const dockerSettingsTemplate: DockerSettingsForm = { + dockerApps: true, + dockerHost: 'localhost', + kubernetesApps: true, + unpinStoppedApps: true, +};