I am learning electron. So I want to open Inspect Element to debug my app.
I already have menu.js.
// #flow
import { app, Menu, shell, BrowserWindow, dialog } from 'electron';
export default class MenuBuilder {
mainWindow: BrowserWindow;
constructor(mainWindow: BrowserWindow) {
this.mainWindow = mainWindow;
}
buildMenu() {
if (
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
) {
this.setupDevelopmentEnvironment();
}
const template =
process.platform === 'darwin'
? this.buildDarwinTemplate()
: this.buildDefaultTemplate();
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
return menu;
}
setupDevelopmentEnvironment() {
this.mainWindow.openDevTools();
this.mainWindow.webContents.on('context-menu', (e, props) => {
const { x, y } = props;
Menu.buildFromTemplate([
{
label: 'Inspect element',
click: () => {
this.mainWindow.inspectElement(x, y);
}
}
]).popup(this.mainWindow);
});
}
buildDarwinTemplate() {
const subMenuAbout = {
label: 'Electron',
submenu: [
{
label: 'Quit',
accelerator: 'Command+Q',
click: () => {
app.quit();
}
}
]
};
const subMenuEdit = {
label: 'Edit',
submenu: [
{ label: 'Undo', accelerator: 'Command+Z', selector: 'undo:' },
{ label: 'Redo', accelerator: 'Shift+Command+Z', selector: 'redo:' },
{ type: 'separator' },
{ label: 'Cut', accelerator: 'Command+X', selector: 'cut:' },
{ label: 'Copy', accelerator: 'Command+C', selector: 'copy:' },
{ label: 'Paste', accelerator: 'Command+V', selector: 'paste:' },
{
label: 'Select All',
accelerator: 'Command+A',
selector: 'selectAll:'
}
]
};
const subMenuViewDev = {
label: 'View',
submenu: [
{
label: 'Reload',
accelerator: 'Command+R',
click: () => {
this.mainWindow.webContents.reload();
}
},
{
label: 'Toggle Full Screen',
accelerator: 'Ctrl+Command+F',
click: () => {
this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
}
},
{
label: 'Toggle Developer Tools',
accelerator: 'Alt+Command+I',
click: () => {
this.mainWindow.toggleDevTools();
}
}
]
};
const subMenuViewProd = {
label: 'View',
submenu: [
{
label: 'Toggle Full Screen',
accelerator: 'Ctrl+Command+F',
click: () => {
this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
}
}
]
};
const subMenuWindow = {
label: 'Window',
submenu: [
{
label: 'Minimize',
accelerator: 'Command+M',
selector: 'performMiniaturize:'
},
{ label: 'Close', accelerator: 'Command+W', selector: 'performClose:' },
{ type: 'separator' },
{ label: 'Bring All to Front', selector: 'arrangeInFront:' }
]
};
const subMenuView =
process.env.NODE_ENV === 'development' ? subMenuViewDev : subMenuViewProd;
return [subMenuAbout, subMenuEdit, subMenuView, subMenuWindow];
}
buildDefaultTemplate() {
const templateDefault = [
{
label: '&File',
submenu: [
{
label: '&Open',
accelerator: 'Ctrl+O',
click: () => {
dialog
.showOpenDialog({ properties: ['openFile', 'multiSelections'] })
.then(response => {
if (!response.canceled) {
// handle fully qualified file name
return response.filePaths[0];
}
return false;
})
.catch(error => console.log(error));
}
},
{
label: '&Close',
accelerator: 'Ctrl+W',
click: () => {
this.mainWindow.close();
}
}
]
},
{
label: '&View',
submenu:
process.env.NODE_ENV === 'development'
? [
{
label: '&Reload',
accelerator: 'Ctrl+R',
click: () => {
this.mainWindow.webContents.reload();
}
},
{
label: 'Toggle &Full Screenn',
accelerator: 'F11',
click: () => {
this.mainWindow.setFullScreen(
!this.mainWindow.isFullScreen()
);
}
},
{
label: 'Toggle &Developer Tools',
accelerator: 'Alt+Ctrl+I',
click: () => {
this.mainWindow.toggleDevTools();
}
}
]
: [
{
label: 'Toggle &Full Screen',
accelerator: 'F11',
click: () => {
this.mainWindow.setFullScreen(
!this.mainWindow.isFullScreen()
);
}
}
]
}
];
return templateDefault;
}
}
After running npm run dev, If I right-click on app window, then I am able to see Inspect element option but nothing is happening If I click on it.
Note :
I am using Kubuntu 22.04
Edit 1:
If I press SHIFT+CTRL+C then I am getting this error :
Edit 2:
I am working on a git repo which will be used for editing image. But currently there are some issues in the code. So I want to debug it through Inspect Element.
You can also clone the repo and run :
npm install
npm run dev
Related
Look I know this is a mild repost of this post but its a bit outdated and I have diffrent packages to worry about aswell as diffrent formatting in my file and file system
I am new to electron so I am sorry if this is a really stupid question
What would be the current best practice for importing Menu() from ./Core/components/Menubar.js
Menubar.js
const { app, Menu } = require('electron')
const isMac = process.platform === 'darwin'
const template = [
// { role: 'appMenu' }
...(isMac ? [{
label: app.name,
submenu: [
{ role: 'about' },
{ type: 'separator' },
{ role: 'services' },
{ type: 'separator' },
{ role: 'hide' },
{ role: 'hideOthers' },
{ role: 'unhide' },
{ type: 'separator' },
{ role: 'quit' }
]
}] : []),
// { role: 'fileMenu' }
{
label: 'File',
submenu: [
isMac ? { role: 'close' } : { role: 'quit' }
]
},
// { role: 'editMenu' }
{
label: 'Edit',
submenu: [
{ role: 'undo' },
{ role: 'redo' },
{ type: 'separator' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
...(isMac ? [
{ role: 'pasteAndMatchStyle' },
{ role: 'delete' },
{ role: 'selectAll' },
{ type: 'separator' },
{
label: 'Speech',
submenu: [
{ role: 'startSpeaking' },
{ role: 'stopSpeaking' }
]
}
] : [
{ role: 'delete' },
{ type: 'separator' },
{ role: 'selectAll' }
])
]
},
// { role: 'viewMenu' }
{
label: 'View',
submenu: [
{ role: 'reload' },
{ role: 'forceReload' },
{ role: 'toggleDevTools' },
{ type: 'separator' },
{ role: 'resetZoom' },
{ role: 'zoomIn' },
{ role: 'zoomOut' },
{ type: 'separator' },
{ role: 'togglefullscreen' }
]
},
// { role: 'windowMenu' }
{
label: 'Window',
submenu: [
{ role: 'minimize' },
{ role: 'zoom' },
...(isMac ? [
{ type: 'separator' },
{ role: 'front' },
{ type: 'separator' },
{ role: 'window' }
] : [
{ role: 'close' }
])
]
},
{
role: 'help',
submenu: [
{
label: 'Learn More',
click: async () => {
const { shell } = require('electron')
await shell.openExternal('https://electronjs.org')
}
}
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
// Export the publicly available function
Main.js
const { app, BrowserWindow, ipcMain, nativeImage, NativeImage, nativeTheme, dialog, Menu } = require('electron')
const path = require('path')
//Start the node file system
const fs = require('fs')
const https = require('https')
const appMenu = require('menu');
//Chart JS testing and config
const Chart = require('chart.js');
const MenuConfig = require("./Core/components/Menubar.js")
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
});
win.loadFile('index.html')
dialog.showOpenDialogSync ([BrowserWindow,])
//Dark theme config
ipcMain.handle('dark-mode:toggle', () => {
if (nativeTheme.shouldUseDarkColors) {
nativeTheme.themeSource = 'light'
} else {
nativeTheme.themeSource = 'dark'
}
return nativeTheme.shouldUseDarkColors
})
ipcMain.handle('dark-mode:system', () => {
nativeTheme.themeSource = 'system'
})
}
const iconName = path.join(__dirname, 'iconForDragAndDrop.png');
const icon = fs.createWriteStream(iconName);
// Create a new file to copy - you can also copy existing files.
fs.writeFileSync(path.join(__dirname, 'drag-and-drop-1.md'), '# First file to test drag and drop')
fs.writeFileSync(path.join(__dirname, 'drag-and-drop-2.md'), '# Second file to test drag and drop')
https.get('https://img.icons8.com/ios/452/drag-and-drop.png', (response) => {
response.pipe(icon);
});
ipcMain.on('ondragstart', (event, filePath) => {
event.sender.startDrag({
file: path.join(__dirname, filePath),
icon: iconName,
})
})
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
I tried to use require() and build() but I can't get the syntax right for this context
For anyone else that comes across this here is how I fixed it assuming template is configured properly.
In Menubar.js
module.exports = Menu.buildFromTemplate(template); On the last line if you set up your template
In main.js
At the top of the file after requiring electron
const applicationMenu = require('./Menubar');
On the line where you are calling app.whenReady
app.whenReady().then(() => {
Menu.setApplicationMenu(applicationMenu);
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
👍
I have a filter dropdown in the header and when users apply the filters I want to run the assigned function according to their choices but I couldn't run it, I got "... is not a function" error.
Also, even if I solve this problem, I will probably have problems in applying more than one filter at the same time, I would be very grateful if anyone could offer a solution in the form of applying filters in multiple ways.
Example Object:
const filters = [
{
section: 'Call Types',
slug: 'call-types',
type: 'multiselect',
options: [
{
label: 'Inbound',
slug: 'inbound',
value: true,
func: (data) =>
data.items.filter((item) => {
return item.className === 'ib'
}),
},
{
label: 'Outbound',
slug: 'outbound',
value: true,
func: (data) =>
data.items.filter((item) => {
return item.className === 'ob'
}),
},
],
},
{
section: 'Data Types',
slug: 'data-types',
type: 'multiselect',
options: [
{
label: 'Sentiment',
slug: 'sentiment',
value: false,
func: (data) =>
data.items.filter((item) => {
return item.d1 === 1
}),
},
{
label: 'Capture Fails',
slug: 'capture-fails',
value: false,
func: (data) =>
data.items.filter((item) => {
return item.d2 > 0.5
}),
},
{
label: 'Audio Notes',
slug: 'audio-notes',
value: false,
func: (data) =>
data.items.filter((item) => {
return item.d1 === 1 && item.d2 > 0.5
}),
},
],
},
{
section: 'Others',
slug: 'others',
type: 'singleselect',
options: [
{
label: 'Show All Agents',
slug: 'show-all-agents',
value: true,
func: (data) =>
data.items.filter((item) => {
return item
}),
},
],
},
]
exports.filters = filters
And here is the method I'm trying to run when users click to "Filter" button.
Timeline vue file:
<template>
<vis-timeline
:groups="filteredData.groups"
:items="filteredData.items"
/>
</template>
<script>
import { mapActions, mapState } from 'vuex'
import VisTimeline from '~/components/UI/VisTimeline.vue'
export default {
components: { VisTimeline },
computed: {
...mapState({
callTimeline: (state) => state.agents.callTimeline,
timelineLoading: (state) => state.agents.loading,
filterOption: (state) => state.agents.filterOption,
}),
filteredData() {
var filtered = Object.assign(
{},
JSON.parse(JSON.stringify(this.callTimeline))
)
return this.filterItems(filtered)
},
},
methods: {
filterItems(data) {
if (this.filterOption) {
this.filterOption.forEach((filter) => {
filter.options.some((option) => {
if (option.value) {
return option.func(data)
}
})
})
}
return data
}
}
}
</script>
Header vue file:
<template>
<a-layout-header style="background: #fff; padding: 0">
<a-dropdown
:trigger="['click']"
:visible="visible"
#visibleChange="handleVisible"
>
<template #overlay>
<a-menu>
<a-menu-item-group
v-for="filter in filters"
:key="filter.slug"
:title="filter.section"
>
<a-menu-item :key="filter.slug">
<a-checkbox
v-for="option in filter.options"
:key="option.slug"
:name="option.slug"
:checked="option.value"
#change="filterChanges"
>
{{ option.label }}
</a-checkbox>
</a-menu-item>
</a-menu-item-group>
<a-menu-divider />
<a-menu-item key="buttons"
><div class="flex justify-between">
<a-button #click="visible = false" type="danger" ghost
>Cancel</a-button
>
<a-button #click="applyFilters" type="primary">Filter</a-button>
</div></a-menu-item
>
</a-menu>
</template>
<div class="mb-1">
<a-button type="primary">
<div class="flex flex-row justify-center space-x-2 items-center">
<a-icon type="filter" />
<span>Filters</span>
<a-icon type="down" />
</div>
</a-button>
</div>
</a-dropdown>
</a-layout-header>
</template>
<script>
import { mapActions} from 'vuex'
import { filters } from '~/utils/Filters'
export default {
name: 'DBHeader',
data() {
return {
visible: false,
filters: filters,
}
},
methods: {
...mapActions({
setFilterOption: 'agents/setFilterOption',
}),
handleVisible(flag) {
this.visible = flag
},
filterChanges(e) {
this.filters.forEach((filter) => {
filter.options.some((option) => {
if (option.slug === e.target.name) {
option.value = e.target.checked
}
})
})
},
applyFilters() {
var filters = Object.assign([], JSON.parse(JSON.stringify(this.filters)))
this.setFilterOption(filters)
this.visible = false
},
},
}
</script>
I created the submenu in electron js and try to change the status of the submenu after it clicked. But I cannot perform the action.
index.js
ipcMain.on('show-context-menu', (event) => {
const template = [
{
label: 'Position',
submenu: [
{
label: 'Bottom Right',
type: 'checkbox',
role: 'bottomRight',
click: () => {
let modifiedMenuItem = changePosition(positioner, 'bottomRight', menuItem);
Menu.setApplicationMenu(Menu.buildFromTemplate(modifiedMenuItem));
//applyMenu(modifiedMenuItem);
menu = Menu.buildFromTemplate(modifiedMenuItem);
Menu.setApplicationMenu(menu);
menu.popup(BrowserWindow.fromWebContents(event.sender));
}
},
{
label: 'Bottom Left',
type: 'checkbox',
role: 'bottomLeft',
click: () => {
let modifiedMenuItem = changePosition(positioner, 'bottomLeft', menuItem);
Menu.setApplicationMenu(Menu.buildFromTemplate(modifiedMenuItem));
//applyMenu(modifiedMenuItem);
menu = Menu.buildFromTemplate(modifiedMenuItem);
Menu.setApplicationMenu(menu);
menu.popup(BrowserWindow.fromWebContents(event.sender));
}
}
]
}
]
menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
menuItem = Menu.getApplicationMenu();
menu.popup(BrowserWindow.fromWebContents(event.sender));
});
let changePosition = (positioner, position, menuItem) => {
let menuTemplate = [{
label: 'Position',
submenu: []
}];
menuItem?.items[0]?.submenu?.items.forEach(m => {
menuTemplate[0].submenu.push({
label: m.label, type: m.type, role: m.role, click: m.click, checked: m.checked
});
});
positioner.move(position);
return menuTemplate;
}
Here after clicking, I am rendering the menu again. But it's not changing the checked status.
Any help on this.
I'm making ionic 3 application. There is verify otp functionality in a sign up page. When the user clicks on sign up button then an alert will be open with otp input with cancel, verify and resend button. What I want to do when user clicks on resend button the same alert should open. I have done this by copying the whole alert code in resend button handler. but it's just opening in first time only. I want to reopen this alert infinitely when a user clicks on resend button.
Below is my alert code
{
let alert = this.alertCtrl.create({
title: 'OTP Sent. Verify OTP',
inputs: [{
name: 'otp',
placeholder: 'OTP',
value: this.otp
}, ],
buttons: [{
text: 'Cancel',
role: 'cancel',
handler: data => {
console.log('Cancel clicked');
}
},
{
text: 'Verify',
handler: data => {
console.log(data.otp);
if (this.responseData.data.otp_sent == data.otp) {
console.log("verfiied");
} else {
// invalid login
return false;
}
}
},
{
text: 'Resend',
handler: data => {
this.authService.postData('mobile=' + this.responseData.data.mobile, 'user/resend').then((result) => {
// console.log(this.otpResend);
let alert = this.alertCtrl.create({
title: 'OTP Sent. Verify OTP',
inputs: [{
name: 'otp',
placeholder: 'OTP',
value: this.otp
}, ],
buttons: [{
text: 'Cancel',
role: 'cancel',
handler: data => {
console.log('Cancel clicked');
}
},
{
text: 'Verify',
handler: data => {
console.log(data.otp);
if (this.responseData.data.otp_sent == data.otp) {
console.log("verfiied");
} else {
// invalid login
return false;
}
}
},
{
text: 'Resend',
handler: data => {
this.authService.postData('mobile=' + this.responseData.data.mobile, 'user/resend').then((result) => {
// console.log(this.otpResend);
});
}
}
]
});
alert.present();
});
}
}
]
});
alert.present();
}
Make a resend function
resend(){
this.authService.postData('mobile=' + this.responseData.data.mobile, 'user/resend').then((result) => {
// console.log(this.otpResend);
let alert1 = this.alertCtrl.create({
title: 'OTP Sent. Verify OTP',
inputs: [{
name: 'otp',
placeholder: 'OTP',
value: this.otp
}, ],
buttons: [{
text: 'Cancel',
role: 'cancel',
handler: data => {
console.log('Cancel clicked');
}
},
{
text: 'Verify',
handler: data => {
console.log(data.otp);
if (this.responseData.data.otp_sent == data.otp) {
console.log("verfiied");
} else {
// invalid login
return false;
}
}
},
{
text: 'Resend',
handler: data => {
this.authService.postData('mobile=' + this.responseData.data.mobile, 'user/resend').then((result) => {
resend();
// console.log(this.otpResend);
});
}
}
]
});
alert1.present();
}
Then call it
{
text: 'Resend',
handler: data =>{
resend();
}
}
has_share(function() {
self.add_items('other', [
{ label: _t('Share'),
callback: self.on_click_share,
classname: 'oe_share',
groups: 'base.group_no_one' },
{ label: _t('Embed'),
callback: self.on_click_share_link,
classname: 'oe_share' },
]);
i want to add groups: 'base.group_no_one' but it will not working.
has_share(function() {
new session.web.Model('res.users').call('has_group', ['base.group_no_one']).done(function(group_status) {
if (group_status == true) {
self.add_items('other', [
{ label: _t('Share'),
callback: self.on_click_share,
classname: 'oe_share' },
{ label: _t('Embed'),
callback: self.on_click_share_link,
classname: 'oe_share' },
]);
}
});
});
using this add group at time of add_item.