I´d like make a site with public routes ('/') and admin routes (/admin).
How can I do it with rest-admin!?
Thanks
You can simply use Router for distinguishing public routes from admin ones, e.g.:
<Router>
<div>
<Route exact path="/" component={Index}/>
<Route path='/admin' component={YourAdmin}/>
</div>
</Router>
Here Index component is you public component (e.g. homepage). And YourAdmin component includes admin-on-rest, e.g.:
class YourAdmin extends Component {
render() {
return (
<Admin ...>
<Resource .../>
<Resource .../>
<Resource .../>
</Admin>
)
}
}
And your admin-page can be secured with built-in admin-on-rest functionality.
Related
This question already has answers here:
react-router scroll to top on every transition
(35 answers)
Closed 11 months ago.
I made a website on Reactjs and I have linked various pages using 'react-router-dom v6'. Whenever I transition from one page to another, the second page always loads on the current location instead of the top. I have tried many tutorials and solutions but they all are valid till v5 of react-router-dom.
I solved the following issue by creating a wrapper function and wrapping it around all the routes.
Follow the following steps:
1: You need to import the following:
import {Routes, Route, BrowserRouter as Router, useLocation} from 'react-router-dom';
import {useLayoutEffect} from 'react';
2: Write a wrapper function just above the "App" function:
const Wrapper = ({children}) => {
const location = useLocation();
useLayoutEffect(() => {
document.documentElement.scrollTo(0, 0);
}, [location.pathname]);
return children
}
3: Now wrap your routes within the wrapper function:
<BrowserRouter>
<Wrapper>
<Navbar />
<Routes>
<Route exact path="/" element={<Home/>} />
<Route path="/Products" element={<Products/>} />
<Route path="/Login" element={<Login/>} />
<Route path="/Aggressive" element={<Aggressive/>} />
<Route path="/Attendance" element={<Attendance/>} />
<Route path="/Choking" element={<Choking/>} />
<Route path="/EmptyCounter" element={<EmptyCounter/>} />
<Route path="/FaceMask" element={<FaceMask/>} />
<Route path="/Fainting" element={<Fainting/>} />
<Route path="/Smoking" element={<Smoking/>} />
<Route path="/SocialDistancing" element={<SocialDistancing/>} />
<Route path="/Weapon" element={<Weapon/>} />
</Routes>
<Footer />
</Wrapper>
</BrowserRouter>
This should solve the issue.
My problem:
If I open http://example.test/profile/create, the New Profile component does not get loaded. Same with the view and edit routes.
In fact, if I click on a Link to profile/create it displays an empty space beneath the Header component. If I try to go to the above address directly via url or by refreshing the page, it shows 404 page not found error.
The Login and Register components work absolutely fine as does the ProfileList (Clicking on a Link or direct navigation both work fine).
<BrowserRouter>
<div>
<Header />
<Switch>
<Route exact path='/' component={ProfilesList} />
<Route exact path='/login' component={LoginComponent} />
<Route exact path='/register' component={RegisterComponent} />
<Route exact path='/profile'>
<Route exact path='/create' component={NewProfile} />
<Route exact path='/view'>
<Route path='/:id' component={ProfileDetail} />
</Route>
<Route exact path='/edit'>
<Route path='/:id' component={EditProfile} />
</Route>
</Route>
</Switch>
</div>
</BrowserRouter>
PS - The below code worked for http://example.test/create AND for http://example.test/1:
<BrowserRouter>
<div>
<Header />
<Switch>
<Route exact path='/' component={ProfilesList} />
<Route path='/login' component={LoginComponent} />
<Route path='/register' component={RegisterComponent} />
<Route path='/create' component={NewProfile} />
<Route path='/:id' component={ProfileDetail} />
</Switch>
</div>
</BrowserRouter>
I'm using Laravel 7 to run my server. The routes/web.php file looks like this -
<?php
Route::view('/{path?}', 'app');
Here's hoping this helps someone.
The key lay in adding a match.path variable. Firstly my App.js file (the entry
place for my app) -
class App extends Component {
render () {
return (
<BrowserRouter>
<div>
<Header />
<Switch>
<Route exact path='/' component={ProfilesList} />
<Route path='/login' component={LoginComponent} />
<Route path='/register' component={RegisterComponent} />
<Route path='/profile' component={Profiles} />
</Switch>
</div>
</BrowserRouter>
)
}
}
Next the Profiles.js file which is handling the routing for profiles link.
const Profiles = ({match}) => {
return (
<BrowserRouter>
<Switch>
<Route path={`${match.path}/create`} component={NewProfile}/>
<Route path={`${match.path}/view`} render={({match}) => (
<Route path={`${match.path}/:id`} component={ProfileDetail}/>
)} />
<Route path={`${match.path}/edit`} render={({match}) => (
<Route path={`${match.path}/:id`} component={EditProfile}/>
)} />
</Switch>
</BrowserRouter>
)
}
export default Profiles
I am still running into the problem of browser throwing 404s when trying to visit the url manually. I know that the answer lies in this answer by Stijn de Witt - I most likely want to do the catch-all solution that he has proposed, but I don't know how to do that. Can someone help?
I am using XML to store my ACL configs, and extended the Zend ACL library to parse the ROLES & Resources, and its working great.
Below is my ACL.XML
<?xml version="1.0" encoding="UTF-8"?>
<permissions>
<roles>
<role name="guest" />
<role name="user" inherits="guest" />
<role name="admin" inherits="user" />
</roles>
<resources>
<module name="account" allow="user">
<controller name="account\controller\account" allow="user">
<action name="login" deny="admin" />
</controller>
</module>
<module name="album" allow="user">
<controller name="album\controller\album" allow="user">
<action name="index" allow="user" />
<action name="add" allow="admin" />
</controller>
</module>
<module name="application" allow="user">
<controller name="application\controller\index" allow="user">
<action name="index" allow="user" />
</controller>
</module>
</resources>
</permissions>
And my Module.php code that is currently called via MvcEvent::EVENT_DISPATCH event,
$serviceManager = $event->getApplication()->getServiceManager();
$configCache = simplexml_load_file(__DIR__.'/config/acl.xml');
$serviceManager->get('memcache')->setItem('cacheXml', $configCache);
//print_r($serviceManager->get('memcache')->getItem('cacheXml'));
$this->_acl = $serviceManager->get('Acl');
$this->_acl->initAcl($configCache);
if (! $this->_acl->_isAllowed('user', $event->getRouteMatch())) {
$url = $event->getRouter()->assemble(array('action' => 'index'), array('name' => 'application'));
$response = $event->getResponse();
$response->getHeaders()->addHeaderLine('Location', $url);
$response->setStatusCode(302);
$response->sendHeaders();
exit;
} else {
echo 'Access granted :) ';
}
How can I CACHE my ACL class ( from service manager ) or by any other means so that the piece of code becomes more persistent and optimized. I am using memcache for my caching.
My approach is to create a ZendAclFactory and from there build an instance or return from cache.
<?php
namespace MyNamespace\Acl;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Permissions\Acl\Acl as ZendAcl;
use Zend\Permissions\Acl\Resource\GenericResource;
use Zend\Permissions\Acl\Role\GenericRole as Role;
class ZendAclFactory implements FactoryInterface
{
private $cache;
public function createService(ServiceLocatorInterface $serviceLocator)
{
$this->cache = $serviceLocator->get('MyCache');
$service = $this->cache->getItem('acl');
if (!empty($service)) {
$service = unserialize($service);
return $service;
}
$service = new ZendAcl();
//initialize you acl here..
$this->cache->addItem('acl', serialize($service));
return $service;
}
}
How do I use React Router with Go?
For example,
I have this in Go:
Echo.Get("/*", *handler which return page with ReactRouter*)
And this in React Router:
React.render((
<Router history={History.createHistory()}>
<Route name="index" path="/" component={Main}>
<Route name="users" path="/users" component={Users}>
<Route name="user" path="/user/:userId" component={User} />
</Route>
<Route path="*" component={NotFound} />
</Route>
</Router>
), document.body)
But I keep getting the index (/) page. All routes behave the same ('/', '/users', '/user/qwe', etc.)
You have to render different routes with new bindings, or handle that binding specifically in your handler function and read out the request object's information.
Echo.Get("/user/:id", getUser)
Echo.Get("/users", listUsers)
Echo.Get("/*", catchAllRemainingCalls)
Hope this helps. Good luck!
I used tabbox to create tabbed page. And each tab includes another zul page. I have 1 controller applied to main page.
If I add some action to component on included zul page, on controller class I cant catch it. If I apply controller to my zul then it creates new instance of controller class.
Here is my code.
<zk>
<style src="/resources/css/default.css" />
<window id="Dealer" class="index"
apply="com.i2i.prm.controller.IndexController" width="100%"
height="100%">
<div class="content" >
<tabbox id="tb" width="100%" forward="onSelect=onSelect">
<tabs id="tabs">
<tab id="info" label="INFO" />
<tab id="create" label="CREATE" />
<tab id="edit" label="EDIT" />
</tabs>
<tabpanels>
<tabpanel id="DealerInfo">
<include id="DealerInfoContent" src="View/Dealer/DealerInfo.zul" />
</tabpanel>
<tabpanel id="DealerCreate">
<include id="DealerCreateContent" src="View/Dealer/DealerCreate.zul" />
</tabpanel>
<tabpanel id="DealerEdit">
<include id="DealerEditContent" src="View/Dealer/DealerEdit.zul" />
</tabpanel>
</tabpanels>
</tabbox>
</div>
</window>
</zk>
And dealerEdit.zul
<zk>
<window title="Dealer Edit" >
<grid width="100%" sizedByContent="true">
<columns>
<column label="" />
</columns>
<rows>
<row >
<label value="Name"></label>
<textbox
value="#{DealerController.user.name }">
</textbox>
</row>
<row>
<label value="Surname"></label>
<textbox
value="#{DealerController.user.surname }" forward="onChange=onASD">
</textbox>
</row>
<row>
<label value="Address"></label>
<textbox
value="#{DealerController.user.address }">
</textbox>
</row>
</rows>
</grid>
</window>
</zk>
This is my controller (IndexController.java) class:
public class IndexController extends GenericForwardComposer {
private User user = new User();;
AnnotateDataBinder binder;
Tabbox tb;
#Override
public void doAfterCompose(Component comp) throws Exception {
// TODO Auto-generated method stub
super.doAfterCompose(comp);
comp.setAttribute(comp.getId() + "Controller", this);
binder = new AnnotateDataBinder(comp);
user.setName("Abdul");
user.setSurname("Rezzak");
user.setAddress("Giderken sağda");
binder.loadAll();
}
public IndexController() {
// TODO Auto-generated constructor stub
}
public void onDFG(ForwardEvent event){
System.out.println(this.hashCode());
}
public void onASD(ForwardEvent event){
System.out.println(this.hashCode());
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
remove <window title="Dealer Edit" > from your included page (DealerEdit.zul) as it forms its own IdSpace. Don't forget to remove the closing </window> tag.
change your onASD method name to include your Include component id i.e. onASD$DealerEditContent. It seems Include also form its own IdSpace and forward event does not work across IdSpace
This should work.
UPDATE 1: I just confirmed that Include is an IdSpace owner component as it implements IdSpace interface so this is the only workaround in your case.
UPDATE 2: I found one more easier way to deal with forwarding events across different IdSpace which is to use component Path within ZUML file for specifying target component. For example in your case you can specify page id in main.zul page
<?page id="main" ?>
and while forwarding event in your included page such as DealerEdit.zul page
<textbox forward="onChange=//main/Dealer.onASD" />
Rest of the code will remain the same.
Reference: http://books.zkoss.org/wiki/ZK_Developer%27s_Reference/Event_Handling/Event_Forwarding#Using_component_Path