MOBILE-3565 login: Implements site page
parent
44da5c36d1
commit
34d6eca9a8
|
@ -18,6 +18,7 @@ import { RouterModule, Routes } from '@angular/router';
|
||||||
import { CoreLoginCredentialsPage } from './pages/credentials/credentials.page';
|
import { CoreLoginCredentialsPage } from './pages/credentials/credentials.page';
|
||||||
import { CoreLoginInitPage } from './pages/init/init.page';
|
import { CoreLoginInitPage } from './pages/init/init.page';
|
||||||
import { CoreLoginSitePage } from './pages/site/site.page';
|
import { CoreLoginSitePage } from './pages/site/site.page';
|
||||||
|
import { CoreLoginSitesPage } from './pages/sites/sites.page';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
|
@ -32,6 +33,10 @@ const routes: Routes = [
|
||||||
path: 'credentials',
|
path: 'credentials',
|
||||||
component: CoreLoginCredentialsPage,
|
component: CoreLoginCredentialsPage,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'sites',
|
||||||
|
component: CoreLoginSitesPage,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
@ -26,6 +26,7 @@ import { CoreLoginRoutingModule } from './login-routing.module';
|
||||||
import { CoreLoginCredentialsPage } from './pages/credentials/credentials.page';
|
import { CoreLoginCredentialsPage } from './pages/credentials/credentials.page';
|
||||||
import { CoreLoginInitPage } from './pages/init/init.page';
|
import { CoreLoginInitPage } from './pages/init/init.page';
|
||||||
import { CoreLoginSitePage } from './pages/site/site.page';
|
import { CoreLoginSitePage } from './pages/site/site.page';
|
||||||
|
import { CoreLoginSitesPage } from './pages/sites/sites.page';
|
||||||
import { CoreLoginHelperProvider } from './services/helper';
|
import { CoreLoginHelperProvider } from './services/helper';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -43,6 +44,7 @@ import { CoreLoginHelperProvider } from './services/helper';
|
||||||
CoreLoginCredentialsPage,
|
CoreLoginCredentialsPage,
|
||||||
CoreLoginInitPage,
|
CoreLoginInitPage,
|
||||||
CoreLoginSitePage,
|
CoreLoginSitePage,
|
||||||
|
CoreLoginSitesPage,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
CoreLoginHelperProvider,
|
CoreLoginHelperProvider,
|
||||||
|
|
|
@ -248,7 +248,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
|
||||||
CoreLoginHelper.instance.treatUserTokenError(siteUrl, error, username, password);
|
CoreLoginHelper.instance.treatUserTokenError(siteUrl, error, username, password);
|
||||||
|
|
||||||
if (error.loggedout) {
|
if (error.loggedout) {
|
||||||
// @todo Go to sites page.
|
this.navCtrl.navigateRoot('/login/sites');
|
||||||
} else if (error.errorcode == 'forcepasswordchangenotice') {
|
} else if (error.errorcode == 'forcepasswordchangenotice') {
|
||||||
// Reset password field.
|
// Reset password field.
|
||||||
this.credForm.controls.password.reset();
|
this.credForm.controls.password.reset();
|
||||||
|
|
|
@ -90,7 +90,7 @@ export class CoreLoginInitPage implements OnInit {
|
||||||
// return this.loginHelper.goToSiteInitialPage();
|
// return this.loginHelper.goToSiteInitialPage();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
await this.navCtrl.navigateRoot('/login/site');
|
await this.navCtrl.navigateRoot('/login/sites');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,7 +321,7 @@ export class CoreLoginSitePage implements OnInit {
|
||||||
CoreLoginHelper.instance.treatUserTokenError(siteData.url, error, siteData.username, siteData.password);
|
CoreLoginHelper.instance.treatUserTokenError(siteData.url, error, siteData.username, siteData.password);
|
||||||
|
|
||||||
if (error.loggedout) {
|
if (error.loggedout) {
|
||||||
// @todo Send the user to sites page.
|
this.navCtrl.navigateRoot('/login/sites');
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
modal.dismiss();
|
modal.dismiss();
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-buttons slot="start">
|
||||||
|
<ion-back-button></ion-back-button>
|
||||||
|
</ion-buttons>
|
||||||
|
|
||||||
|
<ion-title>{{ 'core.settings.sites' | translate }}</ion-title>
|
||||||
|
|
||||||
|
<ion-buttons slot="end">
|
||||||
|
<!-- @todo: Settings button. -->
|
||||||
|
<ion-button *ngIf="sites && sites.length > 0" icon-only (click)="toggleDelete()" [attr.aria-label]="'core.delete' | translate">
|
||||||
|
<ion-icon name="create" ios="md-create"></ion-icon>
|
||||||
|
</ion-button>
|
||||||
|
</ion-buttons>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content>
|
||||||
|
<ion-list>
|
||||||
|
<ion-item (click)="login(site.id)" *ngFor="let site of sites; let idx = index" detail-none>
|
||||||
|
<ion-avatar item-start>
|
||||||
|
<img [src]="site.avatar" core-external-content [siteId]="site.id" alt="{{ 'core.pictureof' | translate:{$a: site.fullName} }}" role="presentation" onError="this.src='assets/img/user-avatar.png'">
|
||||||
|
</ion-avatar>
|
||||||
|
<h2>{{site.fullName}}</h2>
|
||||||
|
<p><core-format-text [text]="site.siteName" clean="true" [siteId]="site.id"></core-format-text></p>
|
||||||
|
<p>{{site.siteUrl}}</p>
|
||||||
|
<ion-badge item-end *ngIf="!showDelete && site.badge">{{site.badge}}</ion-badge>
|
||||||
|
<ion-button *ngIf="showDelete" item-end icon-only clear color="danger" (click)="deleteSite($event, idx)" [attr.aria-label]="'core.delete' | translate">
|
||||||
|
<ion-icon name="trash"></ion-icon>
|
||||||
|
</ion-button>
|
||||||
|
</ion-item>
|
||||||
|
</ion-list>
|
||||||
|
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end">
|
||||||
|
<ion-fab-button (click)="add()" [attr.aria-label]="'core.add' | translate">
|
||||||
|
<ion-icon name="add"></ion-icon>
|
||||||
|
</ion-fab-button>
|
||||||
|
</ion-fab>
|
||||||
|
</ion-content>
|
|
@ -0,0 +1,145 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { CoreDomUtils } from '@/app/services/utils/dom';
|
||||||
|
import { CoreUtils } from '@/app/services/utils/utils';
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
import { CoreSiteBasicInfo, CoreSites } from '@services/sites';
|
||||||
|
import { CoreLogger } from '@singletons/logger';
|
||||||
|
import { CoreLoginHelper } from '../../services/helper';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page that displays a "splash screen" while the app is being initialized.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'page-core-login-sites',
|
||||||
|
templateUrl: 'sites.html',
|
||||||
|
styleUrls: ['sites.scss'],
|
||||||
|
})
|
||||||
|
export class CoreLoginSitesPage implements OnInit {
|
||||||
|
|
||||||
|
sites: CoreSiteBasicInfo[] = [];
|
||||||
|
showDelete = false;
|
||||||
|
|
||||||
|
protected logger: CoreLogger;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.logger = CoreLogger.getInstance('CoreLoginSitesPage');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component being initialized.
|
||||||
|
*
|
||||||
|
* @return Promise resolved when done.
|
||||||
|
*/
|
||||||
|
async ngOnInit(): Promise<void> {
|
||||||
|
const sites = await CoreUtils.instance.ignoreErrors(CoreSites.instance.getSortedSites());
|
||||||
|
|
||||||
|
if (!sites || sites.length == 0) {
|
||||||
|
CoreLoginHelper.instance.goToAddSite(true);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove protocol from the url to show more url text.
|
||||||
|
this.sites = sites.map((site) => {
|
||||||
|
site.siteUrl = site.siteUrl.replace(/^https?:\/\//, '');
|
||||||
|
site.badge = 0;
|
||||||
|
// @todo: getSiteCounter.
|
||||||
|
|
||||||
|
return site;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.showDelete = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go to the page to add a site.
|
||||||
|
*/
|
||||||
|
add(): void {
|
||||||
|
CoreLoginHelper.instance.goToAddSite(false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a site.
|
||||||
|
*
|
||||||
|
* @param e Click event.
|
||||||
|
* @param index Position of the site.
|
||||||
|
* @return Promise resolved when done.
|
||||||
|
*/
|
||||||
|
async deleteSite(e: Event, index: number): Promise<void> {
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
const site = this.sites[index];
|
||||||
|
const siteName = site.siteName || '';
|
||||||
|
|
||||||
|
// @todo: Format text: siteName.
|
||||||
|
|
||||||
|
try {
|
||||||
|
await CoreDomUtils.instance.showDeleteConfirm('core.login.confirmdeletesite', { sitename: siteName });
|
||||||
|
} catch (error) {
|
||||||
|
// User cancelled, stop.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await CoreSites.instance.deleteSite(site.id);
|
||||||
|
|
||||||
|
this.sites.splice(index, 1);
|
||||||
|
this.showDelete = false;
|
||||||
|
|
||||||
|
// If there are no sites left, go to add site.
|
||||||
|
const hasSites = await CoreSites.instance.hasSites();
|
||||||
|
|
||||||
|
if (!hasSites) {
|
||||||
|
CoreLoginHelper.instance.goToAddSite(true, true);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error('Error deleting site ' + site.id, error);
|
||||||
|
CoreDomUtils.instance.showErrorModalDefault(error, 'core.login.errordeletesite', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Login in a site.
|
||||||
|
*
|
||||||
|
* @param siteId The site ID.
|
||||||
|
* @return Promise resolved when done.
|
||||||
|
*/
|
||||||
|
async login(siteId: string): Promise<void> {
|
||||||
|
const modal = await CoreDomUtils.instance.showModalLoading();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const loggedIn = await CoreSites.instance.loadSite(siteId);
|
||||||
|
|
||||||
|
if (loggedIn) {
|
||||||
|
return CoreLoginHelper.instance.goToSiteInitialPage();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error('Error loading site ' + siteId, error);
|
||||||
|
CoreDomUtils.instance.showErrorModalDefault(error, 'Error loading site.');
|
||||||
|
} finally {
|
||||||
|
modal.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle delete.
|
||||||
|
*/
|
||||||
|
toggleDelete(): void {
|
||||||
|
this.showDelete = !this.showDelete;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
.item-ios .item-button[icon-only] ion-icon {
|
||||||
|
font-size: 2.1em;
|
||||||
|
}
|
|
@ -55,7 +55,8 @@ export class CoreLoginHelperProvider {
|
||||||
waitingForBrowser = false;
|
waitingForBrowser = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private location: Location,
|
protected location: Location,
|
||||||
|
protected navCtrl: NavController,
|
||||||
) {
|
) {
|
||||||
this.logger = CoreLogger.getInstance('CoreLoginHelper');
|
this.logger = CoreLogger.getInstance('CoreLoginHelper');
|
||||||
|
|
||||||
|
@ -314,7 +315,7 @@ export class CoreLoginHelperProvider {
|
||||||
*/
|
*/
|
||||||
getLogoutLabel(site?: CoreSite): string {
|
getLogoutLabel(site?: CoreSite): string {
|
||||||
site = site || CoreSites.instance.getCurrentSite();
|
site = site || CoreSites.instance.getCurrentSite();
|
||||||
const config = <CoreSiteConfig> site?.getStoredConfig();
|
const config = site?.getStoredConfig();
|
||||||
|
|
||||||
return 'core.mainmenu.' + (config && config.tool_mobile_forcelogout == '1' ? 'logout' : 'changesite');
|
return 'core.mainmenu.' + (config && config.tool_mobile_forcelogout == '1' ? 'logout' : 'changesite');
|
||||||
}
|
}
|
||||||
|
@ -342,7 +343,7 @@ export class CoreLoginHelperProvider {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Try to get the latest config, maybe the site policy was just added or has changed.
|
// Try to get the latest config, maybe the site policy was just added or has changed.
|
||||||
sitePolicy = <string> await site.getConfig('sitepolicy', true);
|
sitePolicy = await site.getConfig('sitepolicy', true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Cannot get config, try to get the site policy using auth_email_get_signup_settings.
|
// Cannot get config, try to get the site policy using auth_email_get_signup_settings.
|
||||||
const settings = <AuthEmailSignupSettings> await CoreWS.instance.callAjax(
|
const settings = <AuthEmailSignupSettings> await CoreWS.instance.callAjax(
|
||||||
|
@ -413,8 +414,30 @@ export class CoreLoginHelperProvider {
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
async goToAddSite(setRoot?: boolean, showKeyboard?: boolean): Promise<void> {
|
async goToAddSite(setRoot?: boolean, showKeyboard?: boolean): Promise<void> {
|
||||||
// @todo
|
let pageRoute: string;
|
||||||
return Promise.resolve();
|
let params: Params;
|
||||||
|
|
||||||
|
if (this.isFixedUrlSet()) {
|
||||||
|
// Fixed URL is set, go to credentials page.
|
||||||
|
const fixedSites = this.getFixedSites();
|
||||||
|
const url = typeof fixedSites == 'string' ? fixedSites : fixedSites[0].url;
|
||||||
|
|
||||||
|
pageRoute = '/login/credentials';
|
||||||
|
params = { siteUrl: url };
|
||||||
|
} else {
|
||||||
|
pageRoute = '/login/site';
|
||||||
|
params = { showKeyboard: showKeyboard };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setRoot) {
|
||||||
|
await this.navCtrl.navigateRoot(pageRoute, {
|
||||||
|
queryParams: params,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await this.navCtrl.navigateForward(pageRoute, {
|
||||||
|
queryParams: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
Loading…
Reference in New Issue