Twilio Flex Plugin how to add new tab with custom route - twilio

I am using Twilio Flex plugin to customize flex ui in react js.
I want to add one custom link in a sidebar with a new custom component with new route URL like '/shops'.
After loading that component in that body i want to load custom shop.
Check the following screen for more details.
Thanks in advance for a help.

I found this video by Twilio which helped.
https://www.youtube.com/watch?v=ZMjKMoy1RPc
The key points are to add a new View to the View Collection and create a new SideLink which links to it.
import { FlexPlugin } from 'flex-plugin';
import { View, SideLink, Actions } from '#twilio/flex-ui';
import React from 'react';
export default class ShopPlugin extends FlexPlugin {
constructor() {
super('ShopPlugin');
}
init(flex, manager) {
flex.ViewCollection.Content.add(
<View name="shop-view" key="shop-view">
<div>Your Shop View Goes Here</div>
</View>
)
flex.SideNav.Content.add(
<SideLink
showLabel={true}
icon="Thumbup"
iconActive="ThumbupBold"
isActive={activeView === 'shop-view'}
onClick={() => {
Actions.invokeAction('NavigateToView', {viewName: 'shop-view'});
}
>
Shops
</SideLink>
)
}
}

Related

Vaadin Tabs based component created using Designer doesn't show data when bound using its Java companion file

Below is the Vaadin Designer code for simple tab functionality
import {html, PolymerElement} from '#polymer/polymer/polymer-element.js';
import '#vaadin/vaadin-tabs/src/vaadin-tabs.js';
import '#vaadin/vaadin-tabs/src/vaadin-tab.js';
class TestUi extends PolymerElement {
static get template() {
return html`
<style include="shared-styles">
:host {
display: block;
height: 100%;
}
</style>
<vaadin-tabs theme="equal-width-tabs" id="vaadinTabs">
<vaadin-tab id="vaadinTab">
Product Overview
</vaadin-tab>
<vaadin-tab id="vaadinTab1">
Product DetailView
</vaadin-tab>
<vaadin-tab id="vaadinTab2">
Reports
</vaadin-tab>
</vaadin-tabs>
`;
}
static get is() {
return 'test-ui';
}
static get properties() {
return {
// Declare your properties here.
};
}
}
customElements.define(TestUi.is, TestUi);
It's corresponding Java companion file looks as below
import com.vaadin.flow.component.polymertemplate.Id;
import com.vaadin.flow.component.tabs.Tab;
import com.vaadin.flow.component.tabs.Tabs;
import com.vaadin.flow.templatemodel.TemplateModel;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.polymertemplate.PolymerTemplate;
/**
* A Designer generated component for the test-ui template.
*
* Designer will add and remove fields with #Id mappings but
* does not overwrite or otherwise change this file.
*/
#Tag("test-ui")
#JsModule("./src/productdetailview/test-ui.js")
public class TestUi extends PolymerTemplate<TestUi.TestUiModel> {
#Id("vaadinTabs")
private Tabs vaadinTabs;
#Id("vaadinTab")
private Tab vaadinTab;
#Id("vaadinTab1")
private Tab vaadinTab1;
#Id("vaadinTab2")
private Tab vaadinTab2;
/**
* Creates a new TestUi.
*/
public TestUi() {
// You can initialise any data required for the connected UI components here.
vaadinTabs.addSelectedChangeListener(selectedChangeEvent -> {
selectedChangeEvent.getSelectedTab().getElement().getStyle().set("background-color":"blue");
});
}
/**
* This model binds properties between TestUi and test-ui
*/
public interface TestUiModel extends TemplateModel {
// Add setters and getters for template properties here.
}
}
In the above code, My thinking was to start writing the selectedChangeListener Handler directly without doing much but instead this doesn't work and below initialization code needs to be added.
//I have added for one tab but it requires all the tabs to be added
vaadinTabs = new Tabs();
vaadinTab = new Tab();
vaadinTabs.add(vaadinTab);
My question here is why would I need to initialize when the Polymer js code generated using Vaadin Designer clearly defines the tab and it's group?
This is the same issue with Vaadin Grid. Even after defining the columns in the Polymer js, I have to redefine it from the Java component end instead of directly start providing the data via data provider
TLDR; Unfortunately, you have encountered this issue IllegalArgumentException when switching tabs
which is closed as won't fix.
My question here is why would I need to initialize when the Polymer js code generated using Vaadin Designer clearly defines the tab and it's group?
Generally, you don't need to. But Tabs doesn't work as intended in this case. Thus, for this particular component, it's suggested to not mix template/Java logic.
For example, you can verify it with a <vaadin-text-field>, where event is fired correctly.
Java counterpart
#Id("vaadinTextField")
private TextField vaadinTextField;
/**
* Creates a new TestUi.
*/
public TestUi() {
// You can initialise any data required for the connected UI components here.
vaadinTextField.addValueChangeListener(event->{
System.out.println("Event has happened");
});
vaadinTextField.setValueChangeMode(ValueChangeMode.EAGER);
and snippet for the template right after the tabs:
<vaadin-vertical-layout id="vaadinVerticalLayout" style="width: 100%; height: 100%;">
<vaadin-text-field id="vaadinTextField"></vaadin-text-field>
</vaadin-vertical-layout>
Taken from the issue:
So all Tab related API methods in Tabs are completely broken in regard to injected Tabs.
and
Unfortunately we've concluded that there is no sensible way we can support this for now, thus this issue will be a known limitation with Tabs. It will not work as #Id mapped component when the child vaadin-tabs are created in the template file, so you should not try to mix client & server logic and content for the Tabs component.
As a workaround, you could try to use your own component for #Id mapping tabs like:
#Tag("vaadin-tabs")
public IdMappedTabs extends Component {
public IdMappedTabs() {
}
public Registration addSelectionListener(PropertyChangeListener listener) {
return getElement().addPropertyChangeListener("selected", listener);
}
public void setSelectedTabIndex(int index) {
getElement().setProperty("selected", index);
}
}
Edit:
What is the issue with Grid you are having? (There is a good tutorial about Designer, where Grid is used. It might be useful : Vaadin Designer tutorial)

NativeScript Button Not Working on iOS But Works on Android

I have a Github page that I will link to that has all of my code. So basically, I'm using Angular 8 along with NativeScript to build my first app. I've been following a Udemy tutorial and decided to have a series of components. A Menu component which serves as my Home routing path and a series of child routes. The Menu has a TabView which when each tab is clicked, it opens a different component. Right now, I have an About component, a Store component, and a Join component. When each child component route is opened, I wanted to have a BUTTON attach to each child route that routed to another page when clicked. So a button on the About Component that leads to an About Details component that will just have text about the company.
The problem is either with my routing or the page-router-outlet on iOS. I have an iPad and an Android phone I'm using to test things until I get a new Mac to set up the emulators. When I use the page-router-outlet in a certain location on the about-tab.component.html page, it works fine on Android and opens up the About Details component. But on iOS, nothing happens. I click the button...and nothing moves at all.
I've tried moving the page-router-outlet to different locations on the about-tab.component.html file and it either completely breaks the About tab on iOS and the screen is blank (and doesn't show anything, not even the words), or it stays the same. I created a GitHub page...
https://github.com/eoscryptodev/Best-Laces-Out
I've also tried to move around the location of the routes themselves. I tried making the About Details component a child of the About Component, which is a child of the Home component (Main). I also tried putting the component on the same level as the Home (Menu) component.
app-routing.module.ts
import { NgModule, NO_ERRORS_SCHEMA } from '#angular/core';
import { NativeScriptCommonModule } from 'nativescript-angular/common';
import { NativeScriptRouterModule } from 'nativescript-angular/router';
import { Routes } from '#angular/router';
import { MenuComponent } from './menu/menu.component';
import { AboutComponent } from './menu/about/about.component';
import { ShopComponent } from './menu/shop/shop.component';
import { JoinComponent } from './menu/join/join.component';
import { AboutDetailsComponent } from './menu/about-details/about-details.component';
//import { BottomTabComponent } from './tabs/bottom-tab/bottom-tab.component';
//import { JoinPageComponent } from './pages/join-page/join-page.component';
//FIX: You want the path to go from OurHistory(the menu option) to OutHistoryPage. Also figure out how to add the menu to the bottom of the pages.
// Maybe create an ns-path for the BottomTabBar that can be placed on HTML pages.
const routes: Routes =
[
{ path: '', redirectTo: '/home/(HistoryOutlet:OurHistory//MerchOutlet:OurMerch//ClubOutlet:OurClub)', pathMatch: 'full' },
{ path: 'home', component: MenuComponent, children:
[
{ path: 'OurHistory', component: AboutComponent, outlet: 'HistoryOutlet'},
{ path: 'HistoryDetails', component: AboutDetailsComponent, outlet: 'HistoryOutlet' },
{ path: 'OurMerch', component: ShopComponent, outlet: 'MerchOutlet' },
{ path: 'OurClub', component: JoinComponent, outlet: 'ClubOutlet' },
]}, // a root route with an empty path. The route that is loaded when our app starts. SHOULD BE LOGO IMAGE!!
]
about-tab.component.html
<ScrollView orientation="vertical" height="500">
<StackLayout orientation="vertical" backgroundColor="white">
<page-router-outlet name="HistoryOutlet"></page-router-outlet>
<Label text="This is Our History" id="ID1"></Label>
<Button height="50"
width="200"
backgroundColor="black"
text="Who We Are"
id="about-button"
[nsRouterLink]="['/home', { outlets: { HistoryOutlet:[ 'HistoryDetails' ]}} ]">
</Button>
</StackLayout>
</ScrollView>
about-details.component.html
<ns-action-bar title="Details"></ns-action-bar>
<StackLayout>
<Button
text="Go Back"
[nsRouterLink]="['/home', { outlets: { HistoryOutlet: ['OurHistory'] } } ]"
class="about-details">
</Button>
</StackLayout>
I found my solution in the NativeScript Github docs. Under TabView Navigation. I see where I went wrong. I was close, but this answers everything.
https://github.com/NativeScript/docs/blob/6ac877dc3bd551a8e338855e07597ee24358a462/docs/core-concepts/angular-navigation.md

Use DartAngular with dart:html

Is it possible to use default dart library html with angular dart?
ie:
class Test1Component implements OnInit{
#override
void ngOnInit() {
ButtonElement button = querySelector('button');
//Broken code, avoid button to be null.
button.onClick.listen(onClick);
}
void onClick(Event e){
print('Button clicked');
}
}
How can I avoid to get a 'null' button without the using any timers?
Basically I'm using only angular just for the Routes and but I'd like to stick with dart:html to control the DOM and events.
Yes, you can do that, but it's usually not a good idea.
Use instead #ViewChild(...) or similar Angular methods to get references to elements in a components view.
<button #myButton>click me</button>
#ViewChildren('myButton')
set myButton(List<Element> value) {
if(value.isNotEmpty) {
print(value.first);
}
}
If you want to just add a click handler using
<button (click)="onClick">click me</button>
would be the better way but it sounds you are somehow adding the button dynamically and adding a click handler declaratively might not work in this case (would need more info)
EDIT:
If someone like me want to use dart:html instead angular ng code, it's possible to use it
import 'package:angular/angular.dart';
import 'dart:html';
// AngularDart info: https://webdev.dartlang.org/angular
// Components info: https://webdev.dartlang.org/components
#Component(
selector: 'container',
template: '<h1>Test 1</h1><button #test1>Bottone test 1</button>',
)
class Test1Component implements OnInit{
#ViewChild('test1')
ButtonElement button;
#override
void ngOnInit() {
//Verified that button is initialized
print(button);
//Initialize click
button.onClick.listen((e) => print("Clicked"));
}
}

How to add Header Click Listner in Java Vaadin Table?

I am trying to add a very simple listener to my table header as specified in the book of Vaadin. I am using vaadin 6.4.5 in a liferay portlet. But the listener is never called...
table.addListener(new Table.HeaderClickListener() {
public void headerClick(HeaderClickEvent event) {
System.out.println("Column header clicked");
}
// Disable the default sorting behavior
});
table.setSortDisabled(true);
I am also unable to add footer to my table like this..
table.setFooterVisible(true);
table.setColumnFooter("Name", "Average");
table.setColumnFooter("Died At Age", String.valueOf(avgAge));
Both these code snippets were taken from the book of vaadin but they just don't work in my portlet application. please help
I have working Listener Yeah !
table.addHeaderClickListener(new HeaderClickListener() {
#Override
public void headerClick(HeaderClickEvent event) {
System.out.println("click Header");
Object object= event.getPropertyId();
}
});

Can React Native produce UIButton instances in Swift?

I want to use React Native to create some buttons that are wired to trigger methods in a Swift app. Is there a way to access TouchableHighlight instances from within a Swift UIViewController or ViewController class?
There are various options for buttons which you can find on npmjs.org. Below are a couple of options.
https://www.npmjs.com/package/react-native-button
https://www.npmjs.com/package/react-native-icon-button
But you won't find a UIButton instance most likely since that is iOS specific. What you get is a touchable element which acts like a button. You can inspect the code of these modules on GitHub to see how they work.
You can do this without installing additional Node modules by wrapping a <Text> component with a <View> component:
import React from 'react'
class ExampleButton extends React.Component {
constructor(props) {
super(props);
this.pressButton = this.pressButton.bind(this);
}
pressButton() {
console.log("The button was pressed!");
}
render() {
return(
<View>
<Text onPress={this.pressButton}>
Button Text
</Text>
</View>
);
}
}

Resources