I want to display the sidebar items of vx-sidebar according to user role. I'm using acl plugin. There are two users admin and editor. Both have different sidebar items. I have set the roles and everything.But everytime user login, the sidebar items doesn't render initially, I have to refresh the page then the sidebar items render according to role. I am using firebase firestore. And i am setting the initial role as the user.uid found in two different collections of admin and editor.
I have also set the user role in the local storage and vuex.store, but still the elements don't render on initial login.Please help me with this. I have spend days with solving this. But doesn't find solution
acl.js
import Vue from 'vue'
import { AclInstaller, AclCreate, AclRule } from 'vue-acl'
import router from '#/router'
Vue.use(AclInstaller)
let initialRole = localStorage.getItem('userRole')
console.log(initialRole)
export default new AclCreate({
initial: initialRole,
notfound: '/pages/not-authorized',
router,
acceptLocalRules: true,
globalRules: {
admin: new AclRule('admin').generate(),
editor: new AclRule('editor').generate(),
}
})
VxSidebarItem.vue
<div :class="[{'vs-sidebar-item-active':activeLink}, {'disabled-item pointer-events-none': isDisabled}]" class="vs-sidebar--item" v-if="canSee">
computed: {
canSee() {
this.$acl.check(localStorage.getItem('userRole'));
console.log(localStorage.getItem('userRole'))
if(this.to) {
return this.$acl.check(this.$router.match(this.to).meta.rule)
}
return true
}
},
router.js
{
path: '/',
redirect: '/dashboard/jobs'
},
{
path: '/dashboard/jobs',
name: 'Jobs',
component: () => import('./views/tpo/Jobs.vue'),
meta: {
rule:'admin',
}
},
Related
I'm using firebase for user authentication. Except for login/signup flows there are 3 flows called email actions - these include reset password, recover email and verify email.
You can customize the URL that Firebase is calling you, but it has the be the same URL for all actions, while the actual action is passed as query param. Here's an example:
https://example.com/usermgmt?mode=resetPassword&oobCode=ABC123&apiKey=AIzaSy...&lang=fr
// ^^^ from here on starts the dynamic part
My question - how can I use Vue router to load different component based on mode query param?
I know I can create a single component that will dynamically load one of the other 3 based on the query param, but I'm looking for a cleaner way.
I tried looking for "Vue router based on query params" and only found examples how to pass query param into the component as a prop.
Also looked for examples of implementation of Firebase authentication in Vue, but all of the examples focus just on login and signup.
EDIT:
Right now I have a router with this config:
{
path: '/auth/actions',
component: () => import('pages/EmailActions.vue'),
props: (route) => {
return {
mode: route.query.mode
}
}
}
Then, inside EmailActions I have to dynamically show one of 3 components based on mode props.
This file is really redundant as it only contains routing code.
What I'd really like to do is something like this in the router config:
{
path: '/auth/actions',
children:[
{
query: {mode: 'resetPassword'},
component: () => import ('pages/ResetPassword.vue')
},
{
query: {mode: 'recoverEmail'},
component: () => import ('pages/RecoverEmail.vue')
},
{
query: {mode: 'verifyEmail'},
component: () => import ('pages/VerifyEmail.vue')
}
]
}
I need to be able to extend the collection that accounts-ui creates by default of users.
import { Class } from 'meteor/jagi:astronomy';
import { Behavior } from 'meteor/jagi:astronomy-softremove-behavior';
/**
* #class User
*/
const User = Class.create ({
name: 'User',
collection: Meteor.Users,
secured: false,
fields: {
emails: {
type: Email,
optional: true
}
},
behaviors: {
softremove: {
removedFieldName: 'removed',
hasRemovedAtField: true,
removedAtFieldName: 'removedAt'
},
timestamp: {
hasCreatedField: true,
createdFieldName: 'createdAt',
hasUpdatedField: true,
updatedFieldName: 'updatedAt'
}
}
});
export default User;
I wan't use Meteor.user.(), only like to use the User class.
Welcome to Stack Overflow.
The users collection in Meteor is special. Under the hood in Mongo it is a regular collection.
For security reasons, you can't use the users collection like a regular collection, for example you can update your own user record, but you can't browse and edit other users records.
My advice is to create a separate collection for your user profile information. It's not a perfect solution, but it is better to leave the users collection under the control of the Meteor accounts package.
It is possible to extend the collection to store a few profile type data elements, but even that has some wrinkles, because when a user record is updated, the tracker runs, and your UI will refresh (with possible negative side effects if the refresh isn't expected)
I want to hide my tabbar on multiple specific pages. My main focus is to hide it on my Login page, Register page, and a comment page. I have tried tabsHideOnSubPages: true, but when i do this my UserProfile page
(which is a subpage) hides the tabbar. The tabbar must also be visible on the UserProfile page but then again not on my previous mentioned subpages (login, register etc..).
I am currently using Ionic Framework : ionic-angular 3.2.0
Does anyone know how i can fix this?
I can give you a quick hotfix for that.
Copy this Code into your .ts page file.
The function will execute when the page is loaded.
If you want to hide the tabbar then do this line of code:
tabs[key].style.display = 'none';
If you want to show it use this code by simply changing 'none' it to 'flex'.
tabs[key].style.display = 'flex';
This code is an angular function wich basicly means it executes when page is loaded.
ngAfterViewInit()
Full code:
ngAfterViewInit() {
let tabs = document.querySelectorAll('.show-tabbar');
if (tabs !== null) {
Object.keys(tabs).map((key) => {
tabs[key].style.display = 'none';
});
}
}
You can also use this code to show the tabbar again if you leave the page.
ionViewWillLeave() {
let tabs = document.querySelectorAll('.show-tabbar');
if (tabs !== null) {
Object.keys(tabs).map((key) => {
tabs[key].style.display = 'flex';
});
}
}
Hope this helped you.
You can try this.
Just put tabsHideOnSubPages in your config like this:
#NgModule({
declarations: [ MyApp ],
imports: [
IonicModule.forRoot(MyApp, {
tabsHideOnSubPages: true,
}, {}
)],
bootstrap: [IonicApp],
entryComponents: [ MyApp ],
providers: []
})
I've got a form in angular2. If it's dirty (with unsaved changes), I want to restrict the user from navigating away.
Research shows that the canDeactivate route guard is the way to do it.
Google led me to this github file which seems to implement what I want.
import { CanDeactivate } from '#angular/router';
import { FormGroup } from '#angular/forms';
export interface FormComponent {
form: FormGroup;
}
export class PreventUnsavedChangesGuard implements CanDeactivate < FormComponent > {
canDeactivate(component: FormComponent) {
if (component.form.dirty)
return confirm('You have unsaved changes. Are you sure you want to navigate away?');
return true;
}
}
Now, I've put this service in my project, injected it in my form component, added it to my routing module as so...
const routes: Routes = [{
path: '',
loadChildren: 'app/main/main.module#MainModule',
canActivate: [AuthenticationGuard],
}, {
path: 'login',
component: LoginComponent,
canDeactivate: [PreventUnsavedChangesGuard]
}, ]
and included it in the app module's providers array.
Now, it seems to work. In case I have unsaved changes when I click the browser's back button. I get the confirmation dialog. However, when I input a new URL in the address bar, I don't get the confirmation. Also, I'm able to close the tab when I have unsaved changes.
Are these known limitations of canDeactivate, or am I doing something wrong. How do I get the behavior I want? (Confirmation dialog if the user attempts to close tab or navigate away using the address bar?)
I am new to development in Angular2 - Meteor. I have stumbled upon a problem while working with parent-child components. In the parent component, I have meteor subscribing to a collection.
users: any;
constructor(private _zone:NgZone){
var sub = Meteor.subscribe("accounts/users");
Tracker.autorun(function() {
_zone.run(function() {
if(sub.ready()){
this.users = Meteor.users.find().fetch();
console.log(this.users);
}
});
});
}
The user collection has 90 users in total. When the app initially loads, only the current user is found, thus the console log shows one user.
I am not sure if my placement of Tracker.autorun() and NgZone are correct, but after a second of the app loading, the console log shows an array of all 90 users. I assume this happens because the subscribe is not ready at first.
My child component takes in the fetched users as a parameter like this <sd-table [data]="users"></sd-table>. Upon loading of the application, there is only one user that is seen on the drawn template of the child component. Is there any way that the template can be updated when the subscribe happens and all users become accessible?
If you want to refer to this of the current class, don't use function()
users: any;
constructor(private _zone:NgZone){
var sub = Meteor.subscribe("accounts/users");
Tracker.autorun(() => {
_zone.run(() => {
if(sub.ready()){
this.users = Meteor.users.find().fetch();
console.log(this.users);
}
});
});
}
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions