mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	refactor: port MainLayout to TS/SWR (#684)
* refactor: add missing toast field to UI config * refactor: port MainLayout to TS/SWR * refactor: remove unused UI config state * refactor: fix makeStyles import
This commit is contained in:
		
							parent
							
								
									b291515fa4
								
							
						
					
					
						commit
						83778a9928
					
				| @ -3,16 +3,10 @@ import { Alert } from '@material-ui/lab'; | ||||
| import ConditionallyRender from '../ConditionallyRender'; | ||||
| import { Typography } from '@material-ui/core'; | ||||
| import { useStyles } from './Proclamation.styles'; | ||||
| import { IProclamationToast } from '../../../interfaces/uiConfig'; | ||||
| 
 | ||||
| interface IProclamationProps { | ||||
|     toast?: IToast; | ||||
| } | ||||
| 
 | ||||
| interface IToast { | ||||
|     message: string; | ||||
|     id: string; | ||||
|     severity: 'success' | 'info' | 'warning' | 'error'; | ||||
|     link: string; | ||||
|     toast?: IProclamationToast; | ||||
| } | ||||
| 
 | ||||
| const renderProclamation = (id: string) => { | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| import ConditionallyRender from '../../common/ConditionallyRender'; | ||||
| import { matchPath } from 'react-router'; | ||||
| import MainLayout from '../MainLayout'; | ||||
| import { MainLayout } from '../MainLayout/MainLayout'; | ||||
| 
 | ||||
| const LayoutPicker = ({ children, location }) => { | ||||
|     const standalonePages = () => { | ||||
|  | ||||
| @ -1,9 +1,7 @@ | ||||
| import React from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import React, { ReactNode } from 'react'; | ||||
| import classnames from 'classnames'; | ||||
| import { makeStyles } from '@material-ui/styles'; | ||||
| import { makeStyles } from '@material-ui/core/styles'; | ||||
| import { Grid } from '@material-ui/core'; | ||||
| 
 | ||||
| import styles from '../../styles.module.scss'; | ||||
| import ErrorContainer from '../../error/error-container'; | ||||
| import Header from '../../menu/Header/Header'; | ||||
| @ -11,6 +9,7 @@ import Footer from '../../menu/Footer/Footer'; | ||||
| import Proclamation from '../../common/Proclamation/Proclamation'; | ||||
| import BreadcrumbNav from '../../common/BreadcrumbNav/BreadcrumbNav'; | ||||
| import { ReactComponent as Texture } from '../../../assets/img/texture.svg'; | ||||
| import useUiConfig from '../../../hooks/api/getters/useUiConfig/useUiConfig'; | ||||
| 
 | ||||
| const useStyles = makeStyles(theme => ({ | ||||
|     container: { | ||||
| @ -27,18 +26,23 @@ const useStyles = makeStyles(theme => ({ | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
| const MainLayout = ({ children, location, uiConfig }) => { | ||||
| interface IMainLayoutProps { | ||||
|     children: ReactNode | ||||
| } | ||||
| 
 | ||||
| export const MainLayout = ({ children }: IMainLayoutProps) => { | ||||
|     const muiStyles = useStyles(); | ||||
|     const { uiConfig } = useUiConfig(); | ||||
| 
 | ||||
|     return ( | ||||
|         <> | ||||
|             <Header location={location} /> | ||||
|             <Header /> | ||||
|             <Grid container className={muiStyles.container}> | ||||
|                 <div className={classnames(styles.contentWrapper)}> | ||||
|                     <Grid item className={styles.content} xs={12} sm={12}> | ||||
|                         <div | ||||
|                             className={muiStyles.contentContainer} | ||||
|                             style={{ zIndex: '200' }} | ||||
|                             style={{ zIndex: 200 }} | ||||
|                         > | ||||
|                             <BreadcrumbNav /> | ||||
|                             <Proclamation toast={uiConfig.toast} /> | ||||
| @ -52,7 +56,7 @@ const MainLayout = ({ children, location, uiConfig }) => { | ||||
|                                 position: 'fixed', | ||||
|                                 right: '0', | ||||
|                                 bottom: '-4px', | ||||
|                                 zIndex: '1', | ||||
|                                 zIndex: 1, | ||||
|                             }} | ||||
|                         > | ||||
|                             <Texture /> | ||||
| @ -64,9 +68,3 @@ const MainLayout = ({ children, location, uiConfig }) => { | ||||
|         </> | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| MainLayout.propTypes = { | ||||
|     location: PropTypes.object.isRequired, | ||||
| }; | ||||
| 
 | ||||
| export default MainLayout; | ||||
| @ -1,10 +0,0 @@ | ||||
| import { connect } from 'react-redux'; | ||||
| import MainLayout from './MainLayout'; | ||||
| 
 | ||||
| const mapStateToProps = (state, ownProps) => ({ | ||||
|     uiConfig: state.uiConfig.toJS(), | ||||
|     location: ownProps.location, | ||||
|     children: ownProps.children, | ||||
| }); | ||||
| 
 | ||||
| export default connect(mapStateToProps)(MainLayout); | ||||
| @ -9,6 +9,14 @@ export interface IUiConfig { | ||||
|     versionInfo: IVersionInfo; | ||||
|     links: ILinks[]; | ||||
|     disablePasswordAuth?: boolean; | ||||
|     toast?: IProclamationToast | ||||
| } | ||||
| 
 | ||||
| export interface IProclamationToast { | ||||
|     message: string; | ||||
|     id: string; | ||||
|     severity: 'success' | 'info' | 'warning' | 'error'; | ||||
|     link: string; | ||||
| } | ||||
| 
 | ||||
| export interface IFlags { | ||||
|  | ||||
| @ -8,7 +8,6 @@ import strategies from './strategy'; | ||||
| import error from './error'; | ||||
| import user from './user'; | ||||
| import applications from './application'; | ||||
| import uiConfig from './ui-config'; | ||||
| import projects from './project'; | ||||
| import addons from './addons'; | ||||
| import apiCalls from './api-calls'; | ||||
| @ -23,7 +22,6 @@ const unleashStore = combineReducers({ | ||||
|     error, | ||||
|     user, | ||||
|     applications, | ||||
|     uiConfig, | ||||
|     projects, | ||||
|     addons, | ||||
|     apiCalls, | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| import api from './api'; | ||||
| import { dispatchError } from '../util'; | ||||
| import { receiveConfig } from '../ui-config/actions'; | ||||
| import { receiveProjects } from '../project/actions'; | ||||
| import { receiveTagTypes } from '../tag-type/actions'; | ||||
| import { receiveStrategies } from '../strategy/actions'; | ||||
| @ -14,7 +13,6 @@ export function fetchUiBootstrap() { | ||||
|             .fetchUIBootstrap() | ||||
|             .then(json => { | ||||
|                 dispatch(receiveProjects(json.projects)); | ||||
|                 dispatch(receiveConfig(json.uiConfig)); | ||||
|                 dispatch(receiveTagTypes(json)); | ||||
|                 dispatch(receiveStrategies(json.strategies)); | ||||
|             }) | ||||
|  | ||||
| @ -1,97 +0,0 @@ | ||||
| // Jest Snapshot v1, https://goo.gl/fbAQLP | ||||
| 
 | ||||
| exports[`should be default state 1`] = ` | ||||
| Object { | ||||
|   "environment": "", | ||||
|   "flags": Object {}, | ||||
|   "headerBackground": undefined, | ||||
|   "links": Array [ | ||||
|     Object { | ||||
|       "href": "https://docs.getunleash.io/docs?source=oss", | ||||
|       "icon": Object { | ||||
|         "$$typeof": Symbol(react.memo), | ||||
|         "compare": null, | ||||
|         "type": Object { | ||||
|           "$$typeof": Symbol(react.forward_ref), | ||||
|           "render": [Function], | ||||
|         }, | ||||
|       }, | ||||
|       "title": "User documentation", | ||||
|       "value": "Documentation", | ||||
|     }, | ||||
|     Object { | ||||
|       "href": "https://github.com/Unleash", | ||||
|       "icon": "c_github", | ||||
|       "title": "Source code on GitHub", | ||||
|       "value": "GitHub", | ||||
|     }, | ||||
|   ], | ||||
|   "name": "Unleash", | ||||
|   "slogan": "The enterprise ready feature toggle service.", | ||||
|   "version": "3.x", | ||||
| } | ||||
| `; | ||||
| 
 | ||||
| exports[`should be merged state all 1`] = ` | ||||
| Object { | ||||
|   "environment": "dev", | ||||
|   "flags": Object {}, | ||||
|   "headerBackground": "red", | ||||
|   "links": Array [ | ||||
|     Object { | ||||
|       "href": "https://docs.getunleash.io/docs?source=oss", | ||||
|       "icon": Object { | ||||
|         "$$typeof": Symbol(react.memo), | ||||
|         "compare": null, | ||||
|         "type": Object { | ||||
|           "$$typeof": Symbol(react.forward_ref), | ||||
|           "render": [Function], | ||||
|         }, | ||||
|       }, | ||||
|       "title": "User documentation", | ||||
|       "value": "Documentation", | ||||
|     }, | ||||
|     Object { | ||||
|       "href": "https://github.com/Unleash", | ||||
|       "icon": "c_github", | ||||
|       "title": "Source code on GitHub", | ||||
|       "value": "GitHub", | ||||
|     }, | ||||
|   ], | ||||
|   "name": "Unleash", | ||||
|   "slogan": "hello", | ||||
|   "version": "3.x", | ||||
| } | ||||
| `; | ||||
| 
 | ||||
| exports[`should only update headerBackground 1`] = ` | ||||
| Object { | ||||
|   "environment": "", | ||||
|   "flags": Object {}, | ||||
|   "headerBackground": "black", | ||||
|   "links": Array [ | ||||
|     Object { | ||||
|       "href": "https://docs.getunleash.io/docs?source=oss", | ||||
|       "icon": Object { | ||||
|         "$$typeof": Symbol(react.memo), | ||||
|         "compare": null, | ||||
|         "type": Object { | ||||
|           "$$typeof": Symbol(react.forward_ref), | ||||
|           "render": [Function], | ||||
|         }, | ||||
|       }, | ||||
|       "title": "User documentation", | ||||
|       "value": "Documentation", | ||||
|     }, | ||||
|     Object { | ||||
|       "href": "https://github.com/Unleash", | ||||
|       "icon": "c_github", | ||||
|       "title": "Source code on GitHub", | ||||
|       "value": "GitHub", | ||||
|     }, | ||||
|   ], | ||||
|   "name": "Unleash", | ||||
|   "slogan": "The enterprise ready feature toggle service.", | ||||
|   "version": "3.x", | ||||
| } | ||||
| `; | ||||
| @ -1,31 +0,0 @@ | ||||
| import reducer from '../index'; | ||||
| import { receiveConfig } from '../actions'; | ||||
| 
 | ||||
| beforeEach(() => { | ||||
|     localStorage.clear(); | ||||
| }); | ||||
| 
 | ||||
| test('should be default state', () => { | ||||
|     const state = reducer(undefined, {}); | ||||
|     expect(state.toJS()).toMatchSnapshot(); | ||||
| }); | ||||
| 
 | ||||
| test('should be merged state all', () => { | ||||
|     const uiConfig = { | ||||
|         headerBackground: 'red', | ||||
|         slogan: 'hello', | ||||
|         environment: 'dev', | ||||
|     }; | ||||
| 
 | ||||
|     const state = reducer(undefined, receiveConfig(uiConfig)); | ||||
|     expect(state.toJS()).toMatchSnapshot(); | ||||
| }); | ||||
| 
 | ||||
| test('should only update headerBackground', () => { | ||||
|     const uiConfig = { | ||||
|         headerBackground: 'black', | ||||
|     }; | ||||
| 
 | ||||
|     const state = reducer(undefined, receiveConfig(uiConfig)); | ||||
|     expect(state.toJS()).toMatchSnapshot(); | ||||
| }); | ||||
| @ -1,18 +0,0 @@ | ||||
| import api from './api'; | ||||
| import { dispatchError } from '../util'; | ||||
| 
 | ||||
| export const RECEIVE_CONFIG = 'RECEIVE_CONFIG'; | ||||
| export const ERROR_RECEIVE_CONFIG = 'ERROR_RECEIVE_CONFIG'; | ||||
| 
 | ||||
| export const receiveConfig = json => ({ | ||||
|     type: RECEIVE_CONFIG, | ||||
|     value: json, | ||||
| }); | ||||
| 
 | ||||
| export function fetchUIConfig() { | ||||
|     return dispatch => | ||||
|         api | ||||
|             .fetchConfig() | ||||
|             .then(json => dispatch(receiveConfig(json))) | ||||
|             .catch(dispatchError(dispatch, ERROR_RECEIVE_CONFIG)); | ||||
| } | ||||
| @ -1,14 +0,0 @@ | ||||
| import { formatApiPath } from '../../utils/format-path'; | ||||
| import { throwIfNotSuccess } from '../api-helper'; | ||||
| 
 | ||||
| const URI = formatApiPath('api/admin/ui-config'); | ||||
| 
 | ||||
| function fetchConfig() { | ||||
|     return fetch(URI, { credentials: 'include' }) | ||||
|         .then(throwIfNotSuccess) | ||||
|         .then(response => response.json()); | ||||
| } | ||||
| 
 | ||||
| export default { | ||||
|     fetchConfig, | ||||
| }; | ||||
| @ -1,61 +0,0 @@ | ||||
| import { Map as $Map } from 'immutable'; | ||||
| import { LibraryBooks } from '@material-ui/icons'; | ||||
| import { RECEIVE_CONFIG } from './actions'; | ||||
| 
 | ||||
| import { getBasePath } from '../../utils/format-path'; | ||||
| 
 | ||||
| const localStorage = window.localStorage || { | ||||
|     setItem: () => {}, | ||||
|     getItem: () => {}, | ||||
| }; | ||||
| 
 | ||||
| const basePath = getBasePath(); | ||||
| const UI_CONFIG = `${basePath}:ui_config`; | ||||
| 
 | ||||
| const DEFAULT = new $Map({ | ||||
|     headerBackground: undefined, | ||||
|     name: 'Unleash', | ||||
|     version: '3.x', | ||||
|     environment: '', | ||||
|     slogan: 'The enterprise ready feature toggle service.', | ||||
|     flags: {}, | ||||
|     links: [ | ||||
|         { | ||||
|             value: 'Documentation', | ||||
|             icon: LibraryBooks, | ||||
|             href: 'https://docs.getunleash.io/docs?source=oss', | ||||
|             title: 'User documentation', | ||||
|         }, | ||||
|         { | ||||
|             value: 'GitHub', | ||||
|             icon: 'c_github', | ||||
|             href: 'https://github.com/Unleash', | ||||
|             title: 'Source code on GitHub', | ||||
|         }, | ||||
|     ], | ||||
| }); | ||||
| 
 | ||||
| function getInitState() { | ||||
|     try { | ||||
|         const state = JSON.parse(localStorage.getItem(UI_CONFIG)); | ||||
|         return state ? DEFAULT.merge(state) : DEFAULT; | ||||
|     } catch (e) { | ||||
|         return DEFAULT; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function updateConfig(state, config) { | ||||
|     localStorage.setItem(UI_CONFIG, JSON.stringify(config)); | ||||
|     return state.merge(config); | ||||
| } | ||||
| 
 | ||||
| const strategies = (state = getInitState(), action) => { | ||||
|     switch (action.type) { | ||||
|         case RECEIVE_CONFIG: | ||||
|             return updateConfig(state, action.value); | ||||
|         default: | ||||
|             return state; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| export default strategies; | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user