Flutter Getx: How to create single page with url? - flutter-layout

I am trying to create an app single page by using Getx.
When the user changes the URL, the page will change some widgets but Getx still moves to the same page(Observed from the movement when turning pages).
Now, I am using:
getPages: [
GetPage(
name: "Page 1",
page: () {
globals.page= "Page 1";
return Home();
}),
GetPage(
name: "Page 2",
page: () {
globals.page= "Page 2";
return Home();
}),
]
How to solve it?
I am looking like:
getPages: [
GetPage(
name: ["Page 1","Page 2"],
page: () => Home(),
refreshPageWidget: false, //Don't return widget from page:
onSamePage: (String url) { //Do when routing to original page.
if(url == "Page 1"){
globals.page= "Page 1";
}else{
globals.page= "Page 2";
}
}),
]
Can Getx(any package) do this?

It is possible but not complete.
You can change the URL by using
window.history.pushState(null, 'url name', URL);
changePageWidget();
setState((){});
But This will make this app has only one route.
So it can't go back or forward by using the arrow navigation button in the web browser (Although at present this flutter web is not good enough for this.) and you can't use Navigation to manage this page. You must create the function to manage this page.
The big issue with this method is You can't use stateFullWidget
because the stateFullWidget will reset itself when the page widget was changed. So, you need to use state management.
In summary, you can do that as mentioned above but you can't use the arrow navigation button in the web browsers, and you can't use some functions that the flutter makes easy to use.
For me, I am using these steps for some pages that have a tab bar(only change URL).

Related

Hide Product Catalog standard dashlet for all users in Sugarcrm

How can i hide a standard dashlet named "Product Catalog" from the list which gets displayed in the drawer named "Add a Sugar Dashlet". "Add a Sugar Dashlet" drawer gets displayed when user tries to add a dashlet in any dashbaord in Sugarcrm. Hiding should be done in an upgrade safe way.
Note: I am using Sugarcrm Ver 8.0.0 PRO
One way to accomplish this is by creating a custom override of the DashletselectView where you filter out the Dashlet in question.
The code below does so by overriding an internal function of the view, post-processing its results.
custom/clients/base/views/dashletselect/dashletselect.js
({
extendsFrom: "DashletselectView",
_getDashlets: function() {
var dashlets = this._super("_getDashlets", arguments);
return _.filter(dashlets, function (d) { return d.type !== "product-catalog-dashlet"; });
},
})
Then run Quick Repair & Rebuild so that Sugar detects the presence of the custom file and loads it.

Chrome DevTools Protocol: control new tabs

Need to be done: I need to simulate user interactions (journeys) across a chain of sites.
Question: Do you have any tips how to programatically controll a tab opened as a result of a simulated click?
My experience:
I'm using the chrome-remote-interface npm package.
I'm able to simulate a click with a custom ChromeController class which initializes the chrome-remote-interface and these methods:
async simulateClick(selector) {
return await this.evaluate(function (selector) {
document.querySelector(selector).click()
}, selector);
}
/**
* Shamelessly stolen from simple-headless-browser
*/
async evaluate (fn, ...args) {
const exp = args && args.length > 0 ? `(${String(fn)}).apply(null, ${JSON.stringify(args)})` : `(${String(fn)}).apply(null)`
const result = await this.client.Runtime.evaluate({
expression: exp,
returnByValue: true
})
return result
}
Now I would like to interact with the recently opened tab. I can get the targetId of the new tab with the experimenetal Target Domain (prototyping in node cli):
var targets;
chromeController.client.Target.getTargets().then(t => targets = t);
Which results in:
{ targetInfos:
[ { targetId: '97556479-cdb6-415c-97a1-6efa4e00b281',
type: 'page',
title: 'xxx/preview/239402/',
url: 'xxx/preview/239402/' },
{ targetId: 'bbfe11d5-8e4a-4879-9081-10bb7234209c',
type: 'page',
title: 'Document',
url: 'xxx/preview/239402/teaser/0/' } ] }
I am able to switch between the tabs with:
chromeController.client.Target.activateTarget({targetId:'xxx'})
However I'm not able to get any interaction with this, I can't find the connection, how to load it into the Page and Runtime objects.
I've searched in the docs and also tried googling: 'site:chromedevtools.github.io targetId' which only lead me to
> chromeController.client.Browser.getWindowForTarget({targetId: '97556479-cdb6-415c-97a1-6efa4e00b281'}).catch(e => console.log(e.message));
Promise { <pending> }
> 'Browser.getWindowForTarget' wasn't found
I've also tried to Target.setDiscoverTargets({discover: true}) and to close the original tab.
Thanks for any help!
Recently faced this same issue and in short I had to create a new dev tools protocol client for each new target I wanted control over.
My experience is with dev tools protocol using direct communication with websocket but the api is the same so it should be similar. So here is a summary of what I had to do.
Initially looking at the docs I would have assumed Target.attachToTarget should give us control of the new tab but I found that it didn't work.
My workaround was to create a listener that listened for the Target.targetCreated event which provides a targetInfos just like you found with Target.getTargets but for every new target created like a new tab, page, or iframe. Note: you need to enable Target.setDiscoverTargets in order to receive these events over the protocol.
[ { targetId: '97556479-cdb6-415c-97a1-6efa4e00b281',
type: 'page',
title: 'xxx/preview/239402/',
url: 'xxx/preview/239402/' },
{ targetId: 'bbfe11d5-8e4a-4879-9081-10bb7234209c',
type: 'page',
title: 'Document',
url: 'xxx/preview/239402/teaser/0/' } ] }
With that listener I looked for targets that were of type page, you could filter on a specific url if you know what the page will be. With the targetId in hand I requested available websocket targets following the HTTPEndpoints section near the bottom of the devtools home page.
GET /json or /json/list
A list of all available websocket targets.
[ {
"description": "",
"devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/DAB7FB6187B554E10B0BD18821265734",
"id": "DAB7FB6187B554E10B0BD18821265734",
"title": "Yahoo",
"type": "page",
"url": "https://www.yahoo.com/",
"webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/DAB7FB6187B554E10B0BD18821265734"
} ]
I could then launch a new dev tools protocol client using the webSocketDebuggerUrl and have full control over the tab.
I know this is a pretty round about way but, its the only way I was able to make if work.
Although these days it's probably easier to use something like puppeteer to interface with multiple tabs in chrome if you can. Here is the source code to a puppeteer module that follows new tabs that could be good reference for trying to replicate it pageVideoStreamCollector.ts
This is a very late answer but just putting this here if anyone else has the same issue as help on chrome dev tools is very hard to come by. Hope it helps someone out.
I also am getting "Browser.getWindowForTarget wasn't found" on debian, google-chrome-unstable version 61

How to de-register context menu listerners in electron

I previously wrote this question Stacking of Context Menus in Electron and created this issue in the context menu module for electron.
Even though my question above is quite detailed, it got no replies. Then, #sindresorhus recommended I ask this question on StackOverflow:
How do I de-register context menu's in electron? I have a program in which, depending on where you click, a different context menu will show up:
handleContextMenu() {
this.props.contextMenu({
prepend: (params, browserWindow) => [{
label: `Summary ${this.state.msn}`,
click: () => this.createSummary()
},{
label: `Library Compare ${this.state.msn}`,
click: () => this.runLibCompare()
},{
label: `Visualize ${this.state.msn}`,
click: () => dialog.showMessageBox({
type: 'question',
buttons: this.vizButtons,
defaultId: 0,
title: `Choose your visualization`,
message: `Choose your visualization for ${this.state.msn}.`,
}, res => this.visualize(res))
}]
});
};
However, when I right-click on another area, the first context menu pops up, then the second, all the way till the current context menu shows up.
I basically want to de-register a context menu after it has been dismissed. How do I do that?
Update:
Got rid of the context menu and simply fed this to handleContextMenu function:
handleContextMenu = menuItems => {
const menu = new electron.remote.Menu();
menu.append(new electron.remote.MenuItem(menuItems));
menu.popup(electron.remote.getCurrentWindow());
}
And it works! That's that, got rid of the electron-context-menu as well.
This is possible with standard Electron Menu API without additional modules, perhaps using electron-context-menu is just complicating things since that seems to be designed to simplify things for the specific use-case of a standard context menu. With the standard Menu API, you can create and pop-up a menu on each click, so there is no need to "de-register" a menu.
Here's a simplified example, creating a different new context menu with each click:
let menuCount = 1;
window.addEventListener('contextmenu', (e) => {
e.preventDefault();
let menu = new electron.remote.Menu();
menu.append(new electron.remote.MenuItem({label : "Context Menu "+menuCount++}))
menu.popup(electron.remote.getCurrentWindow());
});
On the first right-click you will see a menu with an item "Context Menu 1", on the second right-click, "Context Menu 2", and so on.

How to open a screen as popup from Site Map location

Is there any way to open a custom screen, as placed in the Acumatica menu in the Site map, as a popup (not a new tab) so that it doesn't occupy the existing browser?
I've tried using this, which works ok:
var url = "http://localhost/AcumaticaDB2562/?ScreenId=AC302000&&OpenSourceName=Bills+and+Adjustments&DataID=" + apinvoice.RefNbr;
throw new PXRedirectToUrlException(url, "Open Source")
{
Mode = PXBaseRedirectException.WindowMode.NewWindow
};
The problem is, I don't want the lefthand menu to show up. I just want the screen without any navigation. Is this possible?
I like to use PXRedirectHelper.TryRedirect for calling other graphs. The WindowMode tells the framework how to open the graph. For your question, you will want to use WindowMode.NewWindow as shown in the example below:
var graph = PXGraph.CreateInstance<MyGraph>();
PXRedirectHelper.TryRedirect(graph, PXRedirectHelper.WindowMode.NewWindow);
The enum values for WindowMode are: InLineWindow, New, NewWindow, PopUp, Same.
Alternatively you could do something like this...
throw new PXRedirectRequiredException(graph, true, string.Empty) { Mode = PXBaseRedirectException.WindowMode.NewWindow };

Add a MediaPicker to the General Site Settings

The current project I'm on is utilizing tenant sites. With each site, we want the ability to change the logo through out the tenant site by modifying the its settings (on the admin page, settings > general).
I've added two text fields to the site settings by following this well documented tutorial. However, I'd like the user to be able to pick the logos using the media picker instead of typing in the path.
Currently I have a LogoBarSettings part with its record, driver and handler. I'm not sure how to add the media picker to the my LogoBarSettings and even if I did, must I also create another handler, driver, and record for it? I can't imagine I would but I'm pretty stuck at this point.
Can someone provide some direction on this?
Here is my LogoBarSettings
public class LogoBarSettings : ContentPart<LogoBarSettingsPartRecord>
{
public string ImageUrl
{
get { return Record.ImageUrl; }
set { Record.ImageUrl = value; }
}
public string ImageAltText
{
get { return Record.ImageAltText; }
set { Record.ImageAltText = value; }
}
}
The MediaPicker is invoked through Javascript, so you shouldn't need to change any of your model classes. When the MediaPicker is loaded for a page, it sets up a jQuery event handler for all form elements on the page. Triggering the event orchard-admin-pickimage-open will open the MediaPicker. Supply a callback function to capture the picked media.
Here is a quick example that you can run in Firebug or Chrome Developer Tools from a page which has the MediaPicker loaded, such as a Page editor:
$('form').trigger("orchard-admin-pickimage-open", {
callback: function(data) {
console.log(data);
}})
This should print something similar to this:
Object {img: Object}
img: Object
align: ""
alt: ""
class: ""
height: "64"
html: "<img src="/Media/Default/images/test.jpg" alt="" width="64" height="64"/>"
src: "/Media/Default/images/test.jpg"
style: ""
width: "64"
__proto__: Object
__proto__: Object
The BodyPart editor integrates Orchard's MediaPicker with TinyMce, so you can start looking at that module for a more complete example, specifically Modules\TinyMce\Scripts\plugins\mediapicker\editor_plugin_src.js.

Resources