* I used prime react sidebar.
* It can be used multiple times in the page/application
* It loads different prime react buttons for every sidebar.
* For every sidebar its own onclick function is called when buttons has clicked.
Example screenshots:
project structure:
index.tsx
import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { createStore, combineReducers } from 'redux'; import { Provider } from 'react-redux'; import App from './components/app'; import reducer from './reducer/reducer'; const rootReducer = combineReducers( { reducer: reducer} ); const store = createStore(rootReducer); ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') );
import React from 'react'; import { connect } from 'react-redux'; import { BrowserRouter as Router } from 'react-router-dom'; import Home from './home/home'; import { SET_USER } from '../static/reducerActionTypes'; interface IDispatchProps { setUser: (user: string) => void; } type IProp = IDispatchProps; class App extends React.PureComponent<IProp> { constructor(props: IProp) { super(props); } componentDidMount() { const { setUser } = this.props; setUser('Eda Merdan Biricik'); } componentWillUnmount() { const { setUser } = this.props; setUser(''); } render() { return ( <Router> <div className="app"> <Home /> </div> </Router> ); } } const mapDispatchToProps = (dispatch: any) => ({ setUser: (user: string) => { dispatch({ user, type: SET_USER, }); }, }); export default connect(null, mapDispatchToProps)(App);
import React from 'react'; import MyLeftSidebar from "../sidebar/myLeftSidebar"; import MyRightSidebar from "../sidebar/myRightSidebar"; export default () => ( <> <div> <MyLeftSidebar /> </div> <div> <MyRightSidebar /> </div> </> );
import React from 'react'; import { connect } from 'react-redux'; import CommonSidebar from '../../commons/sidebar/commonSidebar'; const sidebarParameters = { fetchApiParameter: 'left', reducerKey: 'leftSidebarButtons', position: 'left', }; interface IStateProps { user: string; } type IProp = IStateProps; class MyLeftSidebar extends React.PureComponent<IProp> { constructor(props: IProp) { super(props); this.handleClick = this.handleClick.bind(this); } handleClick(params: any) { alert('do want you want. my params: ' + params); } render() { const { user } = this.props; return ( <> {user !== null && <CommonSidebar handleOnClick={this.handleClick} sidebarParameters={sidebarParameters} /> } </> ); } } const mapStateToProps = ({ reducer }: any): IStateProps => { return { user: reducer.get('user', null), }; }; export default connect(mapStateToProps, null)(MyLeftSidebar);
import React from 'react'; import { connect } from 'react-redux'; import CommonSidebar from '../../commons/sidebar/commonSidebar'; const sidebarParameters = { fetchApiParameter: 'right', reducerKey: 'rightSidebarButtons', position: 'right', }; interface IStateProps { user: string; } type IProp = IStateProps; class MyRightSidebar extends React.PureComponent<IProp> { constructor(props: IProp) { super(props); this.handleClick = this.handleClick.bind(this); } handleClick(params: any) { alert('do want you want. my params: ' + params); } render() { const { user } = this.props; return ( <> {user !== null && <CommonSidebar handleOnClick={this.handleClick} sidebarParameters={sidebarParameters} /> } </> ); } } const mapStateToProps = ({ reducer }: any): IStateProps => { return { user: reducer.get('user', null), }; }; export default connect(mapStateToProps, null)(MyRightSidebar);
export const SET_SIDEBAR_BUTTONS = 'SET_SIDEBAR_BUTTONS'; export const SET_USER = 'SET_USER';
import I from 'immutable'; import { SET_SIDEBAR_BUTTONS, SET_USER } from '../static/reducerActionTypes'; interface Action { type: string; data: any; user: string; } export default (state: any = I.Map(), action: Action) => { switch (action.type) { case SET_USER: return state.set('user', action.user); case SET_SIDEBAR_BUTTONS: const { data: { key = '', buttons = I.Map() } = {} } = action; return state.set(key, buttons); default: return state; } };
import React from 'react'; import I from 'immutable'; import { connect } from 'react-redux'; import { Sidebar } from 'primereact/sidebar'; import { CommonSidebarButton } from './commonSidebarButton'; import { getSidebarButtons } from '../../apis/sidebarAPI'; import { SET_SIDEBAR_BUTTONS } from '../../static/reducerActionTypes'; import 'primereact/resources/themes/nova-light/theme.css'; import 'primereact/resources/primereact.min.css'; import './commonSidebar.scss'; interface ISidebarParameters { fetchApiParameter: string; reducerKey: string; position: string; } interface IOwnProps { handleOnClick: (params: object) => void; sidebarParameters: ISidebarParameters; } interface IDispatchProps { setSidebarButtons: (buttons: any) => void; } interface IStateProps { sidebarButtons: any; user: string; } type IProp = IOwnProps & IDispatchProps & IStateProps; class CommonSidebar extends React.PureComponent<IProp> { constructor(props: IProp) { super(props); this.renderButtons = this.renderButtons.bind(this); } async componentDidMount() { const { setSidebarButtons, sidebarParameters, user } = this.props; const buttons = await getSidebarButtons(sidebarParameters.fetchApiParameter, user); setSidebarButtons(buttons); } componentWillUnmount(): void { const { setSidebarButtons } = this.props; setSidebarButtons(I.Map()); } renderButtons() { const { sidebarButtons } = this.props; const isSuccess = I.List.isList(sidebarButtons); const sortedSidebarButtons = isSuccess && sidebarButtons.sortBy((s: any) => s.get('orderNo')); return( <div > {isSuccess && sortedSidebarButtons.map((button:any, idx: number) => ( <CommonSidebarButton button={button} handleOnClick={this.props.handleOnClick} key={idx} /> )) } </div> ); } render() { const { position } = this.props.sidebarParameters; return( <Sidebar className="common-sidebar" modal={false} visible onHide={() => null} showCloseIcon={false} baseZIndex={1} position={position} > {this.renderButtons()} </Sidebar> ); } } const mapStateToProps = ({ reducer }: any, ownProps: IOwnProps): IStateProps => { return { sidebarButtons: reducer.getIn([ownProps.sidebarParameters.reducerKey, 'data'], I.List()), user: reducer.get('user', ''), }; }; const mapDispatchToProps = (dispatch: any, ownProps: IOwnProps): IDispatchProps => ({ setSidebarButtons: (data: any) => { dispatch({ data: { buttons: data, key: ownProps.sidebarParameters.reducerKey }, type: SET_SIDEBAR_BUTTONS, }); }, }); export default connect<IStateProps, IDispatchProps, IOwnProps>( mapStateToProps, mapDispatchToProps )(CommonSidebar);
import React from 'react'; import { Button } from 'primereact/button'; import 'primereact/resources/themes/nova-light/theme.css'; import 'primereact/resources/primereact.min.css'; import 'primeicons/primeicons.css'; import './commonSidebar.scss'; export const CommonSidebarButton = ({ button, handleOnClick }: any) => ( <Button label={button.get('iconLabel')} icon={button.get('iconName')} onClick={() => handleOnClick(button.get('payload'))} /> );
body { div { .common-sidebar { background: #2c7f33; width: 70px; } } } body { .p-sidebar { border: 0px ; padding:0px; } .p-button { background-color: transparent; border-color: #2c7f33; color: #ffffff; font-size: 12px; padding: 10px 5px; margin-top: 10px; } .p-button.p-button-icon-only { width: 100%; } .pi { font-size: 3.00em; } .p-button.p-button-text-icon-left .p-button-text { padding: 0px; } .p-button.p-button-icon-only .p-button-text { display: none; } .p-button:enabled:active { background-color: #1b9e1c; border-color: #ffffff; } .p-button:enabled:focus { box-shadow: 0 0 0 0.1em red; } .p-button:enabled:hover { background-color: #1b9e1c; border-color: #ffffff; } } .p-button-icon-only .p-button-icon-left, .p-button-text-icon-left .p-button-icon-left { position: initial; } .p-button-text { color: #ffffff; font-size: 9px; } .p-button-icon-only .p-button-icon-left{ margin-top: 0px; margin-left: 0px; }
import axios from 'axios'; import I from 'immutable'; export const getSidebarButtons = async(sidebarType: string, user: string) => { try { const { data } = await axios.get( `http://localhost.../getSidebarButtons?sidebarType=${sidebarType}&user=${user}`); return I.fromJS({ data }); } catch (e) { return I.fromJS({ data: { error: 'Error while fetching sidebar buttons', }, }); } };
An example of rest api result: (sidebarType is 'left')
[{ "id":"1","orderNo":"2","iconName":"pi pi-bell", "iconLabel":"Give Your Icon Label If You Want", "payload":{"params":{"componentPath":"/test"}} }, { "id":"2","orderNo":"3","iconName":"pi pi-check", "payload":{"params":{"componentPath":"/test"}} }, { "id":"3","orderNo":"1","iconName":"pi pi-times", "iconLabel":"Give Your Icon Label If You Want", "payload":{"params":{"componentPath":"/test"}} }]
[{ "id":"1","orderNo":"2","iconName":"pi pi-bell", "iconLabel":"Give Your Icon Label If You Want", "payload":{"params":{"componentPath":"/test"}} }]
No comments:
Post a Comment