From 83778a9928a3e0595658f704c9cdc8ce584e41ee Mon Sep 17 00:00:00 2001 From: olav Date: Wed, 9 Feb 2022 14:16:24 +0100 Subject: [PATCH] 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 --- .../common/Proclamation/Proclamation.tsx | 10 +- .../layout/LayoutPicker/LayoutPicker.jsx | 2 +- .../{MainLayout.jsx => MainLayout.tsx} | 26 +++-- .../src/component/layout/MainLayout/index.js | 10 -- frontend/src/interfaces/uiConfig.ts | 8 ++ frontend/src/store/index.js | 2 - frontend/src/store/ui-bootstrap/actions.js | 2 - .../ui-config-store.test.js.snap | 97 ------------------- .../__tests__/ui-config-store.test.js | 31 ------ frontend/src/store/ui-config/actions.js | 18 ---- frontend/src/store/ui-config/api.js | 14 --- frontend/src/store/ui-config/index.js | 61 ------------ 12 files changed, 23 insertions(+), 258 deletions(-) rename frontend/src/component/layout/MainLayout/{MainLayout.jsx => MainLayout.tsx} (81%) delete mode 100644 frontend/src/component/layout/MainLayout/index.js delete mode 100644 frontend/src/store/ui-config/__tests__/__snapshots__/ui-config-store.test.js.snap delete mode 100644 frontend/src/store/ui-config/__tests__/ui-config-store.test.js delete mode 100644 frontend/src/store/ui-config/actions.js delete mode 100644 frontend/src/store/ui-config/api.js delete mode 100644 frontend/src/store/ui-config/index.js diff --git a/frontend/src/component/common/Proclamation/Proclamation.tsx b/frontend/src/component/common/Proclamation/Proclamation.tsx index b5f3cf2e0d..f34e469eb7 100644 --- a/frontend/src/component/common/Proclamation/Proclamation.tsx +++ b/frontend/src/component/common/Proclamation/Proclamation.tsx @@ -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) => { diff --git a/frontend/src/component/layout/LayoutPicker/LayoutPicker.jsx b/frontend/src/component/layout/LayoutPicker/LayoutPicker.jsx index ccea60b3f4..9b86fd9cd0 100644 --- a/frontend/src/component/layout/LayoutPicker/LayoutPicker.jsx +++ b/frontend/src/component/layout/LayoutPicker/LayoutPicker.jsx @@ -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 = () => { diff --git a/frontend/src/component/layout/MainLayout/MainLayout.jsx b/frontend/src/component/layout/MainLayout/MainLayout.tsx similarity index 81% rename from frontend/src/component/layout/MainLayout/MainLayout.jsx rename to frontend/src/component/layout/MainLayout/MainLayout.tsx index 6b3c836c5a..525c9e225a 100644 --- a/frontend/src/component/layout/MainLayout/MainLayout.jsx +++ b/frontend/src/component/layout/MainLayout/MainLayout.tsx @@ -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 ( <> -
+
@@ -52,7 +56,7 @@ const MainLayout = ({ children, location, uiConfig }) => { position: 'fixed', right: '0', bottom: '-4px', - zIndex: '1', + zIndex: 1, }} > @@ -64,9 +68,3 @@ const MainLayout = ({ children, location, uiConfig }) => { ); }; - -MainLayout.propTypes = { - location: PropTypes.object.isRequired, -}; - -export default MainLayout; diff --git a/frontend/src/component/layout/MainLayout/index.js b/frontend/src/component/layout/MainLayout/index.js deleted file mode 100644 index 04ae6cce09..0000000000 --- a/frontend/src/component/layout/MainLayout/index.js +++ /dev/null @@ -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); diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts index 20d16423dc..c041b15c3c 100644 --- a/frontend/src/interfaces/uiConfig.ts +++ b/frontend/src/interfaces/uiConfig.ts @@ -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 { diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js index 0011a0ee61..18fb4f76e6 100644 --- a/frontend/src/store/index.js +++ b/frontend/src/store/index.js @@ -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, diff --git a/frontend/src/store/ui-bootstrap/actions.js b/frontend/src/store/ui-bootstrap/actions.js index 564fac6240..0336f930f7 100644 --- a/frontend/src/store/ui-bootstrap/actions.js +++ b/frontend/src/store/ui-bootstrap/actions.js @@ -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)); }) diff --git a/frontend/src/store/ui-config/__tests__/__snapshots__/ui-config-store.test.js.snap b/frontend/src/store/ui-config/__tests__/__snapshots__/ui-config-store.test.js.snap deleted file mode 100644 index 86708e8a53..0000000000 --- a/frontend/src/store/ui-config/__tests__/__snapshots__/ui-config-store.test.js.snap +++ /dev/null @@ -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", -} -`; diff --git a/frontend/src/store/ui-config/__tests__/ui-config-store.test.js b/frontend/src/store/ui-config/__tests__/ui-config-store.test.js deleted file mode 100644 index d9bcd0d1ed..0000000000 --- a/frontend/src/store/ui-config/__tests__/ui-config-store.test.js +++ /dev/null @@ -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(); -}); diff --git a/frontend/src/store/ui-config/actions.js b/frontend/src/store/ui-config/actions.js deleted file mode 100644 index 2e88eb1018..0000000000 --- a/frontend/src/store/ui-config/actions.js +++ /dev/null @@ -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)); -} diff --git a/frontend/src/store/ui-config/api.js b/frontend/src/store/ui-config/api.js deleted file mode 100644 index c340ea414c..0000000000 --- a/frontend/src/store/ui-config/api.js +++ /dev/null @@ -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, -}; diff --git a/frontend/src/store/ui-config/index.js b/frontend/src/store/ui-config/index.js deleted file mode 100644 index 221e52ebf8..0000000000 --- a/frontend/src/store/ui-config/index.js +++ /dev/null @@ -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;