Problem to use 'vue-sidebar-menu' in Laravel 8 without router-link - laravel

Please help me fix this problem. I create application using Laravel 8, Blade templates and Vue 3 components.
In that i have basic routing in Laravel. I want to add nice looking menu in admin panel https://github.com/yaminncco/vue-sidebar-menu.
Unfortunately, I don't know how to pass my menu structure to this component. When I use the example from the documentation I get an error
Failed to resolve component: router-link
I dont use router in Vue. I see in documentation example with Customize link with InertiaJa but i dont know how use it because i dont use and know InertiaJS.
My simple MainMenu.vue component code:
<template>
<SidebarMenu :menu="menu"></SidebarMenu>
</template>
<script>
import { SidebarMenu } from 'vue-sidebar-menu'
import 'vue-sidebar-menu/dist/vue-sidebar-menu.css'
export default {
name: "MainMenu",
components: {
SidebarMenu
},
data() {
return {
menu: [
{
header: 'Main Navigation',
hiddenOnCollapse: true
},
{
href: '/',
title: 'Dashboard',
icon: 'fa fa-user'
},
{
href: '/charts',
title: 'Charts',
icon: 'fa fa-chart-area',
child: [
{
href: '/charts/sublink',
title: 'Sub Link'
}
]
}
]
}
}
}
</script>
<style scoped>
</style>

Ok, I found a solution to the problem. Need to add own code which create\render simple link in html
in app.js add:
/*remaining application code*/
import { createApp, h } from "vue";
const customLink = {
name: 'CustomLink',
props: ['item'],
render() {
return h('a', this.$slots.default())
}
}
const app = createApp({});
app.component('custom-link', customLink)
/*remaining application code*/
and in Vue Component:
<SidebarMenu :menu="menu" :link-component-name="'custom-link'"></SidebarMenu>

Related

MSTeams Config page Angular 12 SPA with routing

I'm using Angular 12 and am writing a simple group tab app. I'm working on the config page component and the html looks like this:
<br />
<br />
<br />
<p>Configuration 3</p>
<input type="text" placeholder="Some Test" />
In a normal browser, the text and box appears. But if I try to do the same thing via the install to tab path, I don't get the text or input box at all.
I think this might have something to do with routing but can't confirm.
The app-routing-module is pretty simple:
const routes: Routes = [
{
path: '',
component: HomeComponent,
},
{
path: 'configuration',
component: ConfigurationComponent,
},
];
#NgModule({
imports: [
RouterModule.forRoot(routes, {
initialNavigation:
!BrowserUtils.isInIframe() && !BrowserUtils.isInPopup()
? 'enabled'
: 'disabled',
}),
],
exports: [RouterModule],
})
export class AppRoutingModule {}
So what does it take to get the SPA to route to the configuration page when used within teams?
Configuration Component: (URL purposed changed to protect the innocent)
import { Component, OnInit } from '#angular/core';
import { Inject, AfterViewInit, ElementRef } from '#angular/core';
import { DOCUMENT } from '#angular/common';
import * as microsoftTeams from '#microsoft/teams-js';
#Component({
selector: 'app-configuration',
templateUrl: './configuration.component.html',
styleUrls: ['./configuration.component.scss'],
})
export class ConfigurationComponent implements OnInit, AfterViewInit {
constructor(
#Inject(DOCUMENT) private document: Document,
private elementRef: ElementRef
) {}
ngOnInit(): void {
microsoftTeams.initialize();
}
ngAfterViewInit() {
console.log('Initializing ms teams');
microsoftTeams.settings.registerOnSaveHandler((saveEvent) => {
microsoftTeams.settings.setSettings({
entityId: '',
contentUrl: 'https://test.ngrok.io',
suggestedDisplayName: 'Test',
websiteUrl: 'https://test.ngrok.io',
});
saveEvent.notifySuccess();
});
console.log('Register on save');
microsoftTeams.settings.setValidityState(true);
}
}
Thanks,
Nick
In order to render a tab in Teams. You need to make sure that it is iFramable. Please see the document- Tab requirements.
Make sure that you have given the domain in valid domains in your manifest.
Please share more details like console error, what are you using static tab or config and manifest, if issue isn't solve for you
I traced my problem for this particular question to the line:
initialNavigation:
!BrowserUtils.isInIframe() && !BrowserUtils.isInPopup()
? 'enabled'
: 'disabled',
This example is in a lot of the code for SPAs in and Teams Tabs.
I just have it set to 'enabled' for now and I can get beyond the purpose of this question.

How to get Full Calendar event id onClick using Laravel and Vue js?

When a User clicks on an event, I want to show a Modal with the Interview data for that specific id inside of it. All of the events, are interviews stored in a table called interviews.
For some reason in my controller, it's not able to find any id using the find method.
And when I click on an event, no matter which one I click on, it returns an array with all of the event objects for that user. How can I get the event id when clicking on a single event?
Here is a screenshot.
I'm using the Full Calendar Vue Component from the docs.
The $id in the find method is null and not able to find anything for some reason.
----------- UPDATED -----------
CandidateCalendarController.php:
public function index() {
$interviews = Interview::where('candidate_user_id', auth::user()->id)->get();
return Response::json(array(
'events' => $interviews,
), 200);
}
public function show($id) {
$interview = Interview::find($id);
return Response::json(array(
'interview' => $interview,
), 200);
}
router.js:
{
path: '/employer/calendar',
name: 'employer-calendar-index',
component: CalendarIndex,
meta: {
breadcrumb: 'My Calendar',
requiresAuthEmployer: true,
// employerHasPaid: true
},
},
{
path: '/employer/calendar/:interviewId/show',
name: 'employer-calendar-show',
component: CalendarIndex,
meta: {
breadcrumb: 'My Calendar',
requiresAuthEmployer: true,
// employerHasPaid: true
},
}
CandidateCalendar.vue:
<template>
<div>
<b-container fluid>
<b-row>
<b-col>
<FullCalendar
:plugins="calendarPlugins"
:header="{
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
}"
:events="events"
#eventClick="showEvent"
/>
</b-col>
<b-modal ref="eventModal" id="modal-1" title="Update Profile" hide-footer>
{{this.interview}}
</b-modal>
</b-row>
</b-container>
</div>
</template>
<script>
import FullCalendar from "#fullcalendar/vue";
import dayGridPlugin from "#fullcalendar/daygrid";
import timeGridPlugin from "#fullcalendar/timegrid";
import interactionPlugin from "#fullcalendar/interaction";
import listPlugin from "#fullcalendar/list";
import * as candidateInterviewService from '../services/candidate_interview_service.js';
export default {
components: {
FullCalendar
},
data() {
return {
calendarPlugins: [dayGridPlugin, interactionPlugin, timeGridPlugin, listPlugin],
events: [],
interview: []
};
},
created() {
this.getEvents();
},
methods: {
getEvents: async function() {
const response = await candidateInterviewService.loadInterviews();
this.events = response.data.events;
},
showEvent: async function() {
const interviewId = this.$route.params.interviewId;
// this.$refs.eventModal.show();
const response = await candidateInterviewService.loadInterview(interviewId);
console.log(response);
this.interview = response.data.interview;
}
},
};
</script>
<style>
#import "~#fullcalendar/core/main.css";
#import "~#fullcalendar/daygrid/main.css";
#import "~#fullcalendar/timegrid/main.css";
.fc-title, .fc-content {
color: white;
}
.fc-unthemed {
width: 100% !important;
}
</style>
api.php:
Route::get('/candidate/calendar', 'CandidateCalendarController#index')->name('candidate.calendar.index');
Route::get('/candidate/calendar/{calendarId}/show', 'CandidateCalendarController#show')->name('candidate.calendar.show');
candidate_interview_service.js:
export function loadInterviews(data) {
return http().get('/candidate/calendar');
}
export function loadInterview(interviewId) {
return http().get(`/candidate/calendar/${interviewId}/show`);
}
After I click an event and console.log(response), it still says undefined in the url. See screenshot.
Finally I was able to get the id like this and make everything work.
I changed the showEvent async function in CandidateCalendar.vue to this:
showEvent: async function(arg) {
const { id } = this.events.find(
event => event.id === +arg.event.id
);
const response = await candidateInterviewService.loadInterview(id);
this.interview = response.data.interview;
this.$refs.eventModal.show();
},

create dynamic events for a vue component

I have a problem with vue routes. I am using laravel 6 with vue#2.6.10
I want to create the actions button in the header dynamically (the actions are different which depends on the component). This AppHeader component is on every component and on the current component I want to create in the header the events for the current component.
For example the component CategoryDetails I want to have two actions in the header (save and exit).
The route foe the category is this:
path: '/',
redirect: 'dashboard',
component: DashboardLayout,
children: [
{
path: '/categories',
component: Category,
name: 'category',
meta: {
requiresAuth: true
}
},
{
path: '/categories/:CategoryID',
component: CategoryDetails,
name: 'category-details',
props: true,
meta: {
requiresAuth: true
}
},
]
In the component CategoryDetails:
<template>
<div>
<app-header :actions="actions"></app-header>
// other code
</div>
</template>
<script>
import AppHeader from "../../layout/AppHeader";
export default {
name: "CategoryDetails",
components: {AppHeader},
data() {
actions: [{label: 'Save', event: 'category.save'}, {label: 'Exit', event: 'category.exit'}],
},
mounted() {
const vm = this;
Event.$on('category.save', function(){
alert('Save Category!');
});
Event.$on('category.exit', function(){
vm.$router.push({name: 'category'});
});
}
}
</script>
I crated the action object which tells the header component what events to emit and listen to them in this component.
In the AppHeader component:
<template>
<div v-if="typeof(actions) !== 'undefined'" class="col-lg-6 col-sm-5 text-right">
{{ btn.label }}
</div>
</template>
<script>
export default {
name: "AppHeader",
props: [
'actions'
],
methods: {
onActionClick(event) {
Event.$emit(event);
}
}
}
</script>
The Event is the "bus event" defined in the app.js
/**
* Global Event Listener
*/
window.Event = new Vue();
So... let`s tested :)
I am in the category component. Click on the category details ... the actions are in the header (save and exit). Click on exit...we area pushed back to the category component... click again to go in the category details and click save ... the alert appears TWICE.
Exit and enter again ... the alert "Save Category!" appears 3 times.....and so on ...
Why ?
I think the issue is not with your routes. I don't know but try testing with your event locally (not globally) in the component of interest. There may be duplicate action (CategoryDetails).
According to this post: https://forum.vuejs.org/t/component-not-destroying/25008/10
I have to destroy the "zombie effect"
destroyed() {
Event.$off('category.save');
Event.$off('category.exit');
}

Error when using Vue plugin in Laravel: Unknown custom element: <simplert>

I am trying to use the Simplert Vue plugin within my Laravel 5.7 app but I'm getting the following error:
[Vue warn]: Unknown custom element: - did you register the
component correctly? For recursive components, make sure to provide
the "name" option.
I have based my code on answer from this question Vue.js 2- sweet alert package simplert not working
app.js file:
require('./bootstrap');
window.Vue = require('vue');
import Simplert from 'vue2-simplert-plugin'
require('vue2-simplert-plugin/dist/vue2-simplert-plugin.css')
Vue.use(Simplert)
const app = new Vue({
el: '#app',
data: {
obj: {
title: 'Alert Title',
message: 'Alert Message',
type: 'info',
useConfirmBtn: true,
customConfirmBtnText: 'OK'
}
},
methods: {
openSimplert () {
this.$Simplert.open(this.obj)
},
closeSimplert () {
this.$Simplert.close()
}
}
})
home.blade.php template:
#section('content')
// ..
<simplert></simplert>
// ..
package.json:
"dependencies": {
"vue2-simplert-plugin": "^0.5.3"
}
In VSCode, there is a hint on the following line import Simplert from 'vue2-simplert-plugin' in my app.js file:
Could not find a declaration file for module 'vue2-simplert-plugin'.
'x/node_modules/vue2-simplert-plugin/dist/vue2-simplert-plugin.js'
implicitly has an 'any' type.
Could this be the problem?
When registering a Vue component, you need to include a name, list below:
export default {
name: 'example-name',
data() {
return {
}
},
so in your case:
const app = new Vue({
el: '#app',
name: 'example-name'
data: {
obj: {
title: 'Alert Title',
message: 'Alert Message',
type: 'info',
useConfirmBtn: true,
customConfirmBtnText: 'OK'
}
},
methods: {
openSimplert () {
this.$Simplert.open(this.obj)
},
closeSimplert () {
this.$Simplert.close()
}
}
})
ALTERNATIVELY
you should create a file in your resources->js->components folder called something like ExampleComponent.vue. Within here you place all of your template code (what the '#app' div should display).
with that file you should include:
<template>
//code here...
</tempate>
<script>
export default {
name: 'example-component-name',
data() {
return {
obj: {
title: 'Alert Title',
message: 'Alert Message',
type: 'info',
useConfirmBtn: true,
customConfirmBtnText: 'OK'
}
}
},
methods: {
//methods here
}
}
</script>
and then within your app.js file all you need to do is:
require('./bootstrap');
import Simplert from 'vue2-simplert-plugin'
require('vue2-simplert-plugin/dist/vue2-simplert-plugin.css')
Vue.use(Simplert)
Vue.component('example-component-name',require('./components/ExampleComponent.vue').default);
This should help in your situation - let me know :)
I don't know why but i faced the same issu and once the plugin is registered in App.vue, some components works fine with:
<Simplert></Simplert>
and some with
<simplert></simplert>
The only diff is the Uppercase / Lowercase but some components accepts the Uppercase when other not and i must use Lowercase.

Unknown custom element: - did you register the component correctly?

I'm new to vue.js so I know this is a repeated issue but cannot sort this out.
the project works but I cannot add a new component. Nutrition component works, profile does not
My main.js
import Nutrition from './components/nutrition/Nutrition.vue'
import Profile from './components/profile/Profile.vue'
var Vue = require('vue');
var NProgress = require('nprogress');
var _ = require('lodash');
// Plugins
Vue.use(require('vuedraggable'));
// Components
Vue.component('nutrition', Nutrition);
Vue.component('profile', Profile);
// Partials
Vue.partial('payment-fields', require('./components/forms/PaymentFields.html'));
// Filters
Vue.filter('round', function(value, places) {
return _.round(value, places);
});
Vue.filter('format', require('./filters/format.js'))
// Transitions
Vue.transition('slide', {enterClass: 'slideInDown', leaveClass: 'slideOutUp', type: 'animation'})
// Send csrf token
Vue.http.options.headers['X-CSRF-TOKEN'] = Laravel.csrfToken;
// Main Vue instance
new Vue({
el: '#app',
components: {
},
events: {
progress(progress) {
if (progress === 'start') {
NProgress.start();
} else if (progress === 'done') {
NProgress.done();
} else {
NProgress.set(progress);
}
},
'flash.success': function (message) {
this.$refs.flash.showMessage(message, 'success');
},
'flash.error': function (message) {
this.$refs.flash.showMessage(message, 'error');
}
}
});
Profile.vue
<template>
<div class="reddit-list">
<h3>Profile </h3>
<ul>
</ul>
</div>
</template>
<script type="text/babel">
export default {
name: 'profile', // this is what the Warning is talking about.
components: {
},
props: {
model: Array,
}
}
</script>
profile.blade.php
#extends('layouts.app')
#section('title', 'Profile')
#section('body-class', 'profile show')
#section('content')
<script>
window.Laravel.profileData = []
</script>
<profile></profile>
#endsection
Whenever I try to go to this page I get:
[Vue warn]: Unknown custom element: <profile> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
I tried doing a local component such as
Vue.components('profile', {
template: '<div>A custom component!</div>'
});
or even I tried adding the profile into the components in vue but still no luck, can anyone point me in the right direction?
Simply clear the cache on your browser if you run into this problem. Worked pretty well for me
I didn't fixed it but it was fixed by itself it appears some kind of magic called (CACHE). i did have my gulp watch running but i powered off my computer, and then ON again and it works.

Resources