mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
test(e2e): tabs/basic
This commit is contained in:
@@ -1,310 +0,0 @@
|
||||
import { Component, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { Config, IonicApp, IonicModule, App, AlertController, ModalController, ViewController, Tab, Tabs } from '../../../..';
|
||||
|
||||
//
|
||||
// Modal
|
||||
//
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons start>
|
||||
<button ion-button (click)="dismiss()">Cancel</button>
|
||||
</ion-buttons>
|
||||
|
||||
<ion-title>
|
||||
Filter Sessions
|
||||
</ion-title>
|
||||
|
||||
<ion-buttons end>
|
||||
<button ion-button (click)="dismiss()">Done</button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="outer-content">
|
||||
<ion-list>
|
||||
<ion-list-header>Tracks</ion-list-header>
|
||||
|
||||
<ion-item *ngFor="let i of items">
|
||||
<ion-label>Toggle {{i}}</ion-label>
|
||||
<ion-toggle color="secondary"></ion-toggle>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<ion-list>
|
||||
<button ion-item color="danger" detail-none>
|
||||
Reset All Filters
|
||||
</button>
|
||||
<button ion-item color="danger" detail-none (click)="appNavPop()">
|
||||
App Nav Pop
|
||||
</button>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class MyModal {
|
||||
items: any[] = [];
|
||||
|
||||
constructor(private viewCtrl: ViewController, private app: App) {
|
||||
for (var i = 1; i <= 10; i++) {
|
||||
this.items.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
dismiss() {
|
||||
// using the injected ViewController this page
|
||||
// can "dismiss" itself and pass back data
|
||||
this.viewCtrl.dismiss();
|
||||
}
|
||||
|
||||
appNavPop() {
|
||||
this.app.navPop();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Tab 1
|
||||
//
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Settings</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-list-header>
|
||||
Tab 1
|
||||
</ion-list-header>
|
||||
<ion-item *ngFor="let i of items">Item {{i}} {{i}} {{i}} {{i}}</ion-item>
|
||||
</ion-list>
|
||||
<p>
|
||||
<button ion-button (click)="selectPrevious()">Select Previous Tab</button>
|
||||
</p>
|
||||
<p>
|
||||
<button ion-button (click)="appNavPop()">App Nav Pop</button>
|
||||
</p>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class Tab1 {
|
||||
items: any[] = [];
|
||||
|
||||
constructor(private tabs: Tabs, private app: App) {
|
||||
for (var i = 1; i <= 250; i++) {
|
||||
this.items.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
selectPrevious() {
|
||||
this.tabs.select(this.tabs.previousTab());
|
||||
}
|
||||
|
||||
appNavPop() {
|
||||
this.app.navPop();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Tab 2
|
||||
//
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Schedule</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item-sliding *ngFor="let session of sessions" #slidingItem>
|
||||
<ion-item>
|
||||
<h3>{{session.name}} {{session.name}} {{session.name}}</h3>
|
||||
<p>{{session.location}} {{session.location}} {{session.location}}</p>
|
||||
</ion-item>
|
||||
<ion-item-options>
|
||||
<button ion-button color="primary">Speaker<br>Info</button>
|
||||
<button ion-button color="secondary">Add to<br>Favorites</button>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
</ion-list>
|
||||
<p>
|
||||
<button ion-button (click)="selectPrevious()">Select Previous Tab</button>
|
||||
</p>
|
||||
<p>
|
||||
<button ion-button (click)="appNavPop()">App Nav Pop</button>
|
||||
</p>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class Tab2 {
|
||||
sessions: any[] = [];
|
||||
|
||||
constructor(private tabs: Tabs, private app: App) {
|
||||
for (var i = 1; i <= 250; i++) {
|
||||
this.sessions.push({
|
||||
name: 'Name ' + i,
|
||||
location: 'Location: ' + i
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
selectPrevious() {
|
||||
this.tabs.select(this.tabs.previousTab());
|
||||
}
|
||||
|
||||
appNavPop() {
|
||||
this.app.navPop();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Tab 3
|
||||
//
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<button ion-button menuToggle>
|
||||
<ion-icon name="menu"></ion-icon>
|
||||
</button>
|
||||
<ion-title>Stopwatch</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<h2>Tab 3</h2>
|
||||
<p>
|
||||
<button ion-button (click)="presentAlert()">Present Alert</button>
|
||||
<button ion-button (click)="presentModal()">Present Modal</button>
|
||||
</p>
|
||||
<p>
|
||||
<button ion-button (click)="selectPrevious()">Select Previous Tab</button>
|
||||
<button ion-button (click)="appNavPop()">App Nav Pop</button>
|
||||
</p>
|
||||
|
||||
<ion-list [virtualScroll]="items">
|
||||
|
||||
<ion-item *virtualItem="let item">
|
||||
Item: {{item}}
|
||||
</ion-item>
|
||||
|
||||
</ion-list>
|
||||
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class Tab3 {
|
||||
items: number[] = [];
|
||||
|
||||
constructor(private alertCtrl: AlertController, private modalCtrl: ModalController, private tabs: Tabs, private app: App) {
|
||||
for (var i = 0; i < 100; i++) {
|
||||
this.items.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
presentAlert() {
|
||||
let alert = this.alertCtrl.create({
|
||||
title: 'Alert Title!',
|
||||
buttons: ['Dismiss']
|
||||
});
|
||||
alert.present();
|
||||
}
|
||||
|
||||
presentModal() {
|
||||
this.modalCtrl.create(MyModal).present();
|
||||
}
|
||||
|
||||
selectPrevious() {
|
||||
this.tabs.select(this.tabs.previousTab());
|
||||
}
|
||||
|
||||
appNavPop() {
|
||||
this.app.navPop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<ion-menu [content]="content">
|
||||
<ion-header>
|
||||
<ion-toolbar color="secondary">
|
||||
<ion-title>Menu</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<button ion-item menuClose detail-none>
|
||||
Close Menu
|
||||
</button>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-menu>
|
||||
|
||||
<ion-tabs #content (ionChange)="onChange($event)" [color]="myColor">
|
||||
<ion-tab tabTitle="Plain List" tabIcon="star" [root]="root1" (ionSelect)="onSelect($event)"></ion-tab>
|
||||
<ion-tab tabTitle="Schedule" tabIcon="globe" [root]="root2"></ion-tab>
|
||||
<ion-tab tabTitle="Stopwatch" tabIcon="logo-facebook" [root]="root3"></ion-tab>
|
||||
<ion-tab tabTitle="Messages" tabIcon="md-chatboxes" [root]="root1"></ion-tab>
|
||||
<ion-tab tabTitle="My Profile" tabIcon="ios-person" [root]="root2"></ion-tab>
|
||||
</ion-tabs>
|
||||
`
|
||||
})
|
||||
export class TabsPage {
|
||||
root1 = Tab1;
|
||||
root2 = Tab2;
|
||||
root3 = Tab3;
|
||||
myColor: string;
|
||||
|
||||
constructor(config: Config) {
|
||||
this.myColor = (config.get('mode') !== 'ios') ? 'primary' : null;
|
||||
}
|
||||
|
||||
onChange(ev: Tab) {
|
||||
console.log('Changed tab', ev);
|
||||
}
|
||||
|
||||
onSelect(ev: Tab) {
|
||||
console.log('Selected tab', ev);
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `<ion-nav [root]="root"></ion-nav>`
|
||||
})
|
||||
export class E2EApp {
|
||||
root = TabsPage;
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
E2EApp,
|
||||
MyModal,
|
||||
Tab1,
|
||||
Tab2,
|
||||
Tab3,
|
||||
TabsPage
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
IonicModule.forRoot(E2EApp, {
|
||||
tabsHighlight: true,
|
||||
})
|
||||
],
|
||||
bootstrap: [IonicApp],
|
||||
entryComponents: [
|
||||
E2EApp,
|
||||
MyModal,
|
||||
Tab1,
|
||||
Tab2,
|
||||
Tab3,
|
||||
TabsPage
|
||||
]
|
||||
})
|
||||
export class AppModule {}
|
||||
8
src/components/tabs/test/basic/app/app.component.ts
Normal file
8
src/components/tabs/test/basic/app/app.component.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `<ion-nav [root]="root"></ion-nav>`
|
||||
})
|
||||
export class E2EApp {
|
||||
root = 'TabsPage';
|
||||
}
|
||||
36
src/components/tabs/test/basic/app/app.module.ts
Normal file
36
src/components/tabs/test/basic/app/app.module.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { IonicApp, IonicModule } from '../../../../..';
|
||||
|
||||
import { E2EApp } from './app.component';
|
||||
import { Tab1 } from '../components/tab1';
|
||||
import { Tab2 } from '../components/tab2';
|
||||
import { Tab3 } from '../components/tab3';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
E2EApp,
|
||||
Tab1,
|
||||
Tab2,
|
||||
Tab3,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
IonicModule.forRoot(E2EApp, {
|
||||
tabsHighlight: true,
|
||||
}, {
|
||||
links: [
|
||||
{ loadChildren: '../pages/tabs-page/tabs.module#TabsPageModule', name: 'TabsPage' },
|
||||
{ loadChildren: '../components/modal/modal.module#MyModalModule', name: 'MyModal' },
|
||||
]
|
||||
})
|
||||
],
|
||||
bootstrap: [IonicApp],
|
||||
entryComponents: [
|
||||
E2EApp,
|
||||
Tab1,
|
||||
Tab2,
|
||||
Tab3,
|
||||
]
|
||||
})
|
||||
export class AppModule {}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { DeepLinkModule } from '../../../../../..';
|
||||
|
||||
import { MyModal } from './modal';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
MyModal,
|
||||
],
|
||||
imports: [
|
||||
DeepLinkModule.forChild(MyModal)
|
||||
],
|
||||
entryComponents: [
|
||||
MyModal,
|
||||
]
|
||||
})
|
||||
export class MyModalModule {}
|
||||
61
src/components/tabs/test/basic/components/modal/modal.ts
Normal file
61
src/components/tabs/test/basic/components/modal/modal.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { App, AlertController, ViewController } from '../../../../../..';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons start>
|
||||
<button ion-button (click)="dismiss()">Cancel</button>
|
||||
</ion-buttons>
|
||||
|
||||
<ion-title>
|
||||
Filter Sessions
|
||||
</ion-title>
|
||||
|
||||
<ion-buttons end>
|
||||
<button ion-button (click)="dismiss()">Done</button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="outer-content">
|
||||
<ion-list>
|
||||
<ion-list-header>Tracks</ion-list-header>
|
||||
|
||||
<ion-item *ngFor="let i of items">
|
||||
<ion-label>Toggle {{i}}</ion-label>
|
||||
<ion-toggle color="secondary"></ion-toggle>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<ion-list>
|
||||
<button ion-item color="danger" detail-none>
|
||||
Reset All Filters
|
||||
</button>
|
||||
<button ion-item color="danger" detail-none (click)="appNavPop()">
|
||||
App Nav Pop
|
||||
</button>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class MyModal {
|
||||
items: any[] = [];
|
||||
|
||||
constructor(private viewCtrl: ViewController, private app: App) {
|
||||
for (var i = 1; i <= 10; i++) {
|
||||
this.items.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
dismiss() {
|
||||
// using the injected ViewController this page
|
||||
// can "dismiss" itself and pass back data
|
||||
this.viewCtrl.dismiss();
|
||||
}
|
||||
|
||||
appNavPop() {
|
||||
this.app.navPop();
|
||||
}
|
||||
}
|
||||
44
src/components/tabs/test/basic/components/tab1.ts
Normal file
44
src/components/tabs/test/basic/components/tab1.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { App, Tabs } from '../../../../..';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Settings</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-list-header>
|
||||
Tab 1
|
||||
</ion-list-header>
|
||||
<ion-item *ngFor="let i of items">Item {{i}} {{i}} {{i}} {{i}}</ion-item>
|
||||
</ion-list>
|
||||
<p>
|
||||
<button ion-button (click)="selectPrevious()">Select Previous Tab</button>
|
||||
</p>
|
||||
<p>
|
||||
<button ion-button (click)="appNavPop()">App Nav Pop</button>
|
||||
</p>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class Tab1 {
|
||||
items: any[] = [];
|
||||
|
||||
constructor(private tabs: Tabs, private app: App) {
|
||||
for (var i = 1; i <= 250; i++) {
|
||||
this.items.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
selectPrevious() {
|
||||
this.tabs.select(this.tabs.previousTab());
|
||||
}
|
||||
|
||||
appNavPop() {
|
||||
this.app.navPop();
|
||||
}
|
||||
}
|
||||
53
src/components/tabs/test/basic/components/tab2.ts
Normal file
53
src/components/tabs/test/basic/components/tab2.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { App, Tabs } from '../../../../..';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Schedule</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item-sliding *ngFor="let session of sessions" #slidingItem>
|
||||
<ion-item>
|
||||
<h3>{{session.name}} {{session.name}} {{session.name}}</h3>
|
||||
<p>{{session.location}} {{session.location}} {{session.location}}</p>
|
||||
</ion-item>
|
||||
<ion-item-options>
|
||||
<button ion-button color="primary">Speaker<br>Info</button>
|
||||
<button ion-button color="secondary">Add to<br>Favorites</button>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
</ion-list>
|
||||
<p>
|
||||
<button ion-button (click)="selectPrevious()">Select Previous Tab</button>
|
||||
</p>
|
||||
<p>
|
||||
<button ion-button (click)="appNavPop()">App Nav Pop</button>
|
||||
</p>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class Tab2 {
|
||||
sessions: any[] = [];
|
||||
|
||||
constructor(private tabs: Tabs, private app: App) {
|
||||
for (var i = 1; i <= 250; i++) {
|
||||
this.sessions.push({
|
||||
name: 'Name ' + i,
|
||||
location: 'Location: ' + i
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
selectPrevious() {
|
||||
this.tabs.select(this.tabs.previousTab());
|
||||
}
|
||||
|
||||
appNavPop() {
|
||||
this.app.navPop();
|
||||
}
|
||||
}
|
||||
65
src/components/tabs/test/basic/components/tab3.ts
Normal file
65
src/components/tabs/test/basic/components/tab3.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { App, AlertController, ModalController, Tabs } from '../../../../..';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<button ion-button menuToggle>
|
||||
<ion-icon name="menu"></ion-icon>
|
||||
</button>
|
||||
<ion-title>Stopwatch</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<h2>Tab 3</h2>
|
||||
<p>
|
||||
<button ion-button (click)="presentAlert()">Present Alert</button>
|
||||
<button ion-button (click)="presentModal()">Present Modal</button>
|
||||
</p>
|
||||
<p>
|
||||
<button ion-button (click)="selectPrevious()">Select Previous Tab</button>
|
||||
<button ion-button (click)="appNavPop()">App Nav Pop</button>
|
||||
</p>
|
||||
|
||||
<ion-list [virtualScroll]="items">
|
||||
|
||||
<ion-item *virtualItem="let item">
|
||||
Item: {{item}}
|
||||
</ion-item>
|
||||
|
||||
</ion-list>
|
||||
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class Tab3 {
|
||||
items: number[] = [];
|
||||
|
||||
constructor(private alertCtrl: AlertController, private modalCtrl: ModalController, private tabs: Tabs, private app: App) {
|
||||
for (var i = 0; i < 100; i++) {
|
||||
this.items.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
presentAlert() {
|
||||
let alert = this.alertCtrl.create({
|
||||
title: 'Alert Title!',
|
||||
buttons: ['Dismiss']
|
||||
});
|
||||
alert.present();
|
||||
}
|
||||
|
||||
presentModal() {
|
||||
this.modalCtrl.create('MyModal').present();
|
||||
}
|
||||
|
||||
selectPrevious() {
|
||||
this.tabs.select(this.tabs.previousTab());
|
||||
}
|
||||
|
||||
appNavPop() {
|
||||
this.app.navPop();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { DeepLinkModule } from '../../../../../..';
|
||||
|
||||
import { TabsPage } from './tabs';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
TabsPage,
|
||||
],
|
||||
imports: [
|
||||
DeepLinkModule.forChild(TabsPage)
|
||||
],
|
||||
entryComponents: [
|
||||
TabsPage,
|
||||
]
|
||||
})
|
||||
export class TabsPageModule {}
|
||||
51
src/components/tabs/test/basic/pages/tabs-page/tabs.ts
Normal file
51
src/components/tabs/test/basic/pages/tabs-page/tabs.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Config, Tab } from '../../../../../..';
|
||||
|
||||
import { Tab1 } from '../../components/tab1';
|
||||
import { Tab2 } from '../../components/tab2';
|
||||
import { Tab3 } from '../../components/tab3';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<ion-menu [content]="content">
|
||||
<ion-header>
|
||||
<ion-toolbar color="secondary">
|
||||
<ion-title>Menu</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<button ion-item menuClose detail-none>
|
||||
Close Menu
|
||||
</button>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-menu>
|
||||
|
||||
<ion-tabs #content (ionChange)="onChange($event)" [color]="myColor">
|
||||
<ion-tab tabTitle="Plain List" tabIcon="star" [root]="root1" (ionSelect)="onSelect($event)"></ion-tab>
|
||||
<ion-tab tabTitle="Schedule" tabIcon="globe" [root]="root2"></ion-tab>
|
||||
<ion-tab tabTitle="Stopwatch" tabIcon="logo-facebook" [root]="root3"></ion-tab>
|
||||
<ion-tab tabTitle="Messages" tabIcon="md-chatboxes" [root]="root1"></ion-tab>
|
||||
<ion-tab tabTitle="My Profile" tabIcon="ios-person" [root]="root2"></ion-tab>
|
||||
</ion-tabs>
|
||||
`
|
||||
})
|
||||
export class TabsPage {
|
||||
root1 = Tab1;
|
||||
root2 = Tab2;
|
||||
root3 = Tab3;
|
||||
myColor: string;
|
||||
|
||||
constructor(config: Config) {
|
||||
this.myColor = (config.get('mode') !== 'ios') ? 'primary' : null;
|
||||
}
|
||||
|
||||
onChange(ev: Tab) {
|
||||
console.log('Changed tab', ev);
|
||||
}
|
||||
|
||||
onSelect(ev: Tab) {
|
||||
console.log('Selected tab', ev);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user