import qs from 'qs' ; import { AppConfigType , NavLayout , RoutableComponentClass } from '../types' ; import pathToRegexp from 'path-to-regexp' ; export function overwrite ( newProps , history , appConfig ) { let matchedScreen ; for ( const screenName in appConfig . screens ) { if ( appConfig . screens . hasOwnProperty ( screenName ) ) { const screen = appConfig . screens [ screenName ] ; let pathReg = new RegExp ( '^\/_s\/' + screenName + '/?$' ) ; if ( screen . path ) { pathReg = pathToRegexp ( screen . path ) ; } if ( pathReg . test ( window . location . pathname ) ) { matchedScreen = { screen , screenName } ; } } } if ( matchedScreen ) { const path = getPathWithPassProps ( matchedScreen . screenName , matchedScreen . screen , newProps ) ; history . replace ( path ) ; } else { console . error ( 'Could not match current screen' ) ; } } export default function push ( layout , history , appConfig , href ? ) { if ( layout . component ) { if ( appConfig . screens [ layout . component . name ] ) { if ( href ) { history . push ( href ) ; } else { const path = getPathWithPassProps ( String ( layout . component . name ) , appConfig . screens [ layout . component . name ] , layout . component . passProps ) ; history . push ( path ) ; } } else { console . error ( 'Unknown screen: ' + layout . component . name ) ; } } else { console . error ( 'No component to push' ) ; } } function getPathWithPassProps ( screenName , screen , passProps ) { if ( screen && screen . path ) { if ( screen . path . indexOf ( ':' ) > - 1 ) { let convertProps = passProps ; if ( screen . urlConvert ) { convertProps = screen . urlConvert ( convertProps ) ; } const extraQS = getExtraQS ( screen . paramKeys , convertProps ) ; return screen . toPath ( convertProps , { encode : ( str ) : string => { return str ; } } ) + extraQS ; } else { return screen . path + '?' + qs . stringify ( passProps ) ; } } else { return `/_s/${ screenName }` + '?' + qs . stringify ( passProps ) ; } } function getExtraQS ( paramKeys , passProps ) { const extra = { } ; const keyNames = paramKeys . map ( ( k ) => k . name ) . filter ( ( n ) => ! ! n ) ; let hasExtra = false ; Object . keys ( passProps ) . forEach ( pk => { if ( keyNames . indexOf ( pk ) === - 1 ) { extra [ pk ] = passProps [ pk ] ; hasExtra = true ; } } ) ; return hasExtra ? '?' + qs . stringify ( extra ) : '' ; }