MOBILE-3807 mainmenu: Add new user menu modal
parent
289e8e1ce7
commit
81fdd00902
|
@ -0,0 +1,33 @@
|
||||||
|
// (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 { NgModule } from '@angular/core';
|
||||||
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { CoreMainMenuUserButtonComponent } from './user-menu-button/user-menu-button';
|
||||||
|
import { CoreMainMenuUserMenuComponent } from './user-menu/user-menu';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
CoreMainMenuUserButtonComponent,
|
||||||
|
CoreMainMenuUserMenuComponent,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
CoreSharedModule,
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
CoreMainMenuUserButtonComponent,
|
||||||
|
CoreMainMenuUserMenuComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class CoreMainMenuComponentsModule {}
|
|
@ -0,0 +1,9 @@
|
||||||
|
<core-user-avatar
|
||||||
|
*ngIf="siteInfo"
|
||||||
|
[user]="siteInfo"
|
||||||
|
class="core-bar-button-image clickable"
|
||||||
|
[linkProfile]="false"
|
||||||
|
(ariaButtonClick)="openUserMenu($event)"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
></core-user-avatar>
|
|
@ -0,0 +1,55 @@
|
||||||
|
// (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 { Component } from '@angular/core';
|
||||||
|
import { CoreSiteInfo } from '@classes/site';
|
||||||
|
import { CoreSites } from '@services/sites';
|
||||||
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
|
import { CoreMainMenuUserMenuComponent } from '../user-menu/user-menu';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component to display an avatar on the header to open user menu.
|
||||||
|
*
|
||||||
|
* Example: <core-user-menu-button></core-user-menu-button>
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'core-user-menu-button',
|
||||||
|
templateUrl: 'user-menu-button.html',
|
||||||
|
})
|
||||||
|
export class CoreMainMenuUserButtonComponent {
|
||||||
|
|
||||||
|
siteInfo?: CoreSiteInfo;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
const currentSite = CoreSites.getRequiredCurrentSite();
|
||||||
|
|
||||||
|
// @TODO: Check if the page where I currently am is at level 0.
|
||||||
|
this.siteInfo = currentSite.getInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open User menu
|
||||||
|
*
|
||||||
|
* @param event Click event.
|
||||||
|
*/
|
||||||
|
openUserMenu(event: Event): void {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
CoreDomUtils.openModal<void>({
|
||||||
|
component: CoreMainMenuUserMenuComponent,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-buttons slot="start">
|
||||||
|
<ion-button fill="clear" (click)="close($event)" [attr.aria-label]="'core.close' | translate">
|
||||||
|
<ion-icon name="fas-times" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||||
|
</ion-button>
|
||||||
|
</ion-buttons>
|
||||||
|
<h1>
|
||||||
|
{{'core.user.account' | translate}}
|
||||||
|
</h1>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content>
|
||||||
|
<core-loading [hideUntil]="true">
|
||||||
|
<ion-list>
|
||||||
|
<ion-item class="ion-text-center core-user-profile-maininfo" *ngIf="siteInfo">
|
||||||
|
<core-user-avatar [user]="siteInfo" [userId]="siteInfo.userid" [linkProfile]="false"></core-user-avatar>
|
||||||
|
<ion-label>
|
||||||
|
<h2>{{ siteInfo.fullname }}</h2>
|
||||||
|
<p class="core-usermenu-siteinfo core-usermenu-sitename">
|
||||||
|
<core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
|
||||||
|
</core-format-text>
|
||||||
|
</p>
|
||||||
|
<p class="core-usermenu-siteinfo core-usermenu-siteurl">{{ siteUrl }}</p>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item button class="ion-text-wrap core-usermenu-handler" (click)="openUserProfile($event)"
|
||||||
|
[attr.aria-label]="'core.user.details' | translate" detail="true">
|
||||||
|
<ion-icon name="fas-user" slot="start" aria-hidden="true"></ion-icon>
|
||||||
|
<ion-label>
|
||||||
|
<p class="item-heading">{{ 'core.user.details' | translate }}</p>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item class="ion-text-center" *ngIf="(!handlers || !handlers.length) && !handlersLoaded">
|
||||||
|
<ion-label><ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner></ion-label>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item button *ngFor="let handler of handlers" class="ion-text-wrap" (click)="handlerClicked($event, handler)"
|
||||||
|
[ngClass]="['core-user-menu-handler', handler.class || '']" [hidden]="handler.hidden"
|
||||||
|
[attr.aria-label]="handler.title | translate" detail="true">
|
||||||
|
<ion-icon *ngIf="handler.icon" [name]="handler.icon" slot="start" aria-hidden="true"></ion-icon>
|
||||||
|
<ion-label>
|
||||||
|
<p class="item-heading">{{ handler.title | translate }}</p>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item button (click)="openPreferences($event)" [attr.aria-label]="'core.settings.preferences' | translate" detail="true">
|
||||||
|
<ion-icon name="fas-wrench" slot="start" aria-hidden="true"></ion-icon>
|
||||||
|
<ion-label>
|
||||||
|
<p class="item-heading">{{ 'core.settings.preferences' | translate }}</p>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
</ion-list>
|
||||||
|
</core-loading>
|
||||||
|
</ion-content>
|
||||||
|
<ion-footer class="ion-padding">
|
||||||
|
<ion-button (click)="logout($event)" expand="block" color="danger" [attr.aria-label]="logoutLabel | translate" class="ion-text-wrap">
|
||||||
|
<ion-icon name="fas-sign-out-alt" slot="start" aria-hidden="true"></ion-icon>
|
||||||
|
{{ logoutLabel | translate }}
|
||||||
|
</ion-button>
|
||||||
|
</ion-footer>
|
|
@ -0,0 +1,38 @@
|
||||||
|
@import "~theme/globals";
|
||||||
|
|
||||||
|
:host {
|
||||||
|
.core-user-profile-maininfo::part(native) {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
::ng-deep {
|
||||||
|
core-user-avatar {
|
||||||
|
display: block;
|
||||||
|
--core-avatar-size: var(--core-large-avatar-size);
|
||||||
|
height: calc(var(--core-avatar-size) + 16px);
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin: 8px auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@if ($core-user-hide-siteinfo) {
|
||||||
|
.core-usermenu-siteinfo {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@if ($core-user-hide-sitename) {
|
||||||
|
.core-usermenu-sitename {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@if ($core-user-hide-siteurl) {
|
||||||
|
.core-usermenu-siteurl {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
// (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 { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
|
import { CoreSiteInfo } from '@classes/site';
|
||||||
|
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
||||||
|
import { CoreUser, CoreUserProfile } from '@features/user/services/user';
|
||||||
|
import { CoreUserProfileHandlerData, CoreUserDelegate, CoreUserDelegateService } from '@features/user/services/user-delegate';
|
||||||
|
import { CoreNavigator } from '@services/navigator';
|
||||||
|
import { CoreSites } from '@services/sites';
|
||||||
|
import { ModalController } from '@singletons';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component to display a user menu.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'core-main-menu-user-menu',
|
||||||
|
templateUrl: 'user-menu.html',
|
||||||
|
styleUrls: ['user-menu.scss'],
|
||||||
|
})
|
||||||
|
export class CoreMainMenuUserMenuComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
siteInfo?: CoreSiteInfo;
|
||||||
|
siteName?: string;
|
||||||
|
logoutLabel = 'core.mainmenu.changesite';
|
||||||
|
siteUrl?: string;
|
||||||
|
handlers: CoreUserProfileHandlerData[] = [];
|
||||||
|
handlersLoaded = false;
|
||||||
|
user?: CoreUserProfile;
|
||||||
|
|
||||||
|
protected subscription!: Subscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async ngOnInit(): Promise<void> {
|
||||||
|
|
||||||
|
const currentSite = CoreSites.getRequiredCurrentSite();
|
||||||
|
|
||||||
|
this.siteInfo = currentSite.getInfo();
|
||||||
|
this.siteName = currentSite.getSiteName();
|
||||||
|
this.siteUrl = currentSite.getURL();
|
||||||
|
this.logoutLabel = CoreLoginHelper.getLogoutLabel(currentSite);
|
||||||
|
|
||||||
|
// Load the handlers.
|
||||||
|
if (this.siteInfo) {
|
||||||
|
this.user = await CoreUser.getProfile(this.siteInfo.userid);
|
||||||
|
|
||||||
|
this.subscription = CoreUserDelegate.getProfileHandlersFor(this.user).subscribe((handlers) => {
|
||||||
|
if (!handlers || !this.user) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handlers = [];
|
||||||
|
handlers.forEach((handler) => {
|
||||||
|
if (handler.type == CoreUserDelegateService.TYPE_NEW_PAGE) {
|
||||||
|
this.handlers.push(handler.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.handlersLoaded = CoreUserDelegate.areHandlersLoaded(this.user.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens User profile page.
|
||||||
|
*
|
||||||
|
* @param event Click event.
|
||||||
|
*/
|
||||||
|
async openUserProfile(event: Event): Promise<void> {
|
||||||
|
if (!this.siteInfo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.close(event);
|
||||||
|
|
||||||
|
CoreNavigator.navigateToSitePath('user/about', {
|
||||||
|
params: {
|
||||||
|
userId: this.siteInfo.userid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens preferences.
|
||||||
|
*
|
||||||
|
* @param event Click event.
|
||||||
|
*/
|
||||||
|
async openPreferences(event: Event): Promise<void> {
|
||||||
|
await this.close(event);
|
||||||
|
|
||||||
|
CoreNavigator.navigateToSitePath('preferences');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A handler was clicked.
|
||||||
|
*
|
||||||
|
* @param event Click event.
|
||||||
|
* @param handler Handler that was clicked.
|
||||||
|
*/
|
||||||
|
async handlerClicked(event: Event, handler: CoreUserProfileHandlerData): Promise<void> {
|
||||||
|
if (!this.user) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.close(event);
|
||||||
|
|
||||||
|
handler.action(event, this.user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logout the user.
|
||||||
|
*
|
||||||
|
* @param event Click event
|
||||||
|
*/
|
||||||
|
async logout(event: Event): Promise<void> {
|
||||||
|
await this.close(event);
|
||||||
|
|
||||||
|
CoreSites.logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close modal.
|
||||||
|
*/
|
||||||
|
async close(event: Event): Promise<void> {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
await ModalController.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.subscription?.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,97 +5,76 @@
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
|
|
||||||
<h1><core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0"></core-format-text></h1>
|
<h1><core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0"></core-format-text></h1>
|
||||||
|
|
||||||
|
<ion-buttons slot="end">
|
||||||
|
<core-user-menu-button></core-user-menu-button>
|
||||||
|
</ion-buttons>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<core-loading [hideUntil]="!loggedOut">
|
<ion-list>
|
||||||
<ion-list>
|
<ion-item class="ion-text-center" *ngIf="(!handlers || !handlers.length) && !handlersLoaded">
|
||||||
<ion-item button *ngIf="siteInfo" class="ion-text-wrap" core-user-link [userId]="siteInfo.userid" detail="true">
|
<ion-label><ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner></ion-label>
|
||||||
<core-user-avatar [user]="siteInfo" slot="start"></core-user-avatar>
|
</ion-item>
|
||||||
|
<ion-item button *ngFor="let handler of handlers" [ngClass]="['core-moremenu-handler', handler.class || '']"
|
||||||
|
(click)="openHandler(handler)" [attr.aria-label]="handler.title | translate" detail="true">
|
||||||
|
<ion-icon [name]="handler.icon" slot="start" aria-hidden="true"></ion-icon>
|
||||||
|
<ion-label>
|
||||||
|
<p class="item-heading">{{ handler.title | translate}}</p>
|
||||||
|
</ion-label>
|
||||||
|
<ion-badge slot="end" *ngIf="handler.showBadge" [hidden]="handler.loading || !handler.badge" aria-hidden="true">
|
||||||
|
{{handler.badge}}
|
||||||
|
</ion-badge>
|
||||||
|
<span *ngIf="handler.showBadge && handler.badge && handler.badgeA11yText" class="sr-only">
|
||||||
|
{{ handler.badgeA11yText | translate: {$a : handler.badge } }}
|
||||||
|
</span>
|
||||||
|
<ion-spinner slot="end" *ngIf="handler.showBadge && handler.loading" [attr.aria-label]="'core.loading' | translate">
|
||||||
|
</ion-spinner>
|
||||||
|
</ion-item>
|
||||||
|
<ng-container *ngFor="let item of customItems">
|
||||||
|
<ion-item button *ngIf="item.type != 'embedded'" [href]="item.url" [attr.aria-label]="item.label" core-link
|
||||||
|
[capture]="item.type == 'app'" [inApp]="item.type == 'inappbrowser'" class="core-moremenu-customitem" detail="true"
|
||||||
|
[detailIcon]="item.type == 'browser' ? 'open-outline' : 'chevron-forward'">
|
||||||
|
<ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<p class="item-heading">{{siteInfo.fullname}}</p>
|
<p class="item-heading">{{item.label}}</p>
|
||||||
<p class="core-moremenu-siteinfo core-moremenu-sitename">
|
|
||||||
<core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
|
|
||||||
</core-format-text>
|
|
||||||
</p>
|
|
||||||
<p class="core-moremenu-siteinfo core-moremenu-siteurl">{{ siteUrl }}</p>
|
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<core-spacer></core-spacer>
|
<ion-item button *ngIf="item.type == 'embedded'" (click)="openItem(item)" [attr.aria-label]="item.label"
|
||||||
<ion-item class="ion-text-center" *ngIf="(!handlers || !handlers.length) && !handlersLoaded">
|
class="core-moremenu-customitem" detail="true">
|
||||||
<ion-label><ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner></ion-label>
|
<ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
|
||||||
</ion-item>
|
|
||||||
<ion-item button *ngFor="let handler of handlers" [ngClass]="['core-moremenu-handler', handler.class || '']"
|
|
||||||
(click)="openHandler(handler)" [attr.aria-label]="handler.title | translate" detail="true">
|
|
||||||
<ion-icon [name]="handler.icon" slot="start" aria-hidden="true"></ion-icon>
|
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<p class="item-heading">{{ handler.title | translate}}</p>
|
<p class="item-heading">{{item.label}}</p>
|
||||||
</ion-label>
|
|
||||||
<ion-badge slot="end" *ngIf="handler.showBadge" [hidden]="handler.loading || !handler.badge" aria-hidden="true">
|
|
||||||
{{handler.badge}}
|
|
||||||
</ion-badge>
|
|
||||||
<span *ngIf="handler.showBadge && handler.badge && handler.badgeA11yText" class="sr-only">
|
|
||||||
{{ handler.badgeA11yText | translate: {$a : handler.badge } }}
|
|
||||||
</span>
|
|
||||||
<ion-spinner slot="end" *ngIf="handler.showBadge && handler.loading" [attr.aria-label]="'core.loading' | translate">
|
|
||||||
</ion-spinner>
|
|
||||||
</ion-item>
|
|
||||||
<ng-container *ngFor="let item of customItems">
|
|
||||||
<ion-item button *ngIf="item.type != 'embedded'" [href]="item.url" [attr.aria-label]="item.label" core-link
|
|
||||||
[capture]="item.type == 'app'" [inApp]="item.type == 'inappbrowser'" class="core-moremenu-customitem" detail="true"
|
|
||||||
[detailIcon]="item.type == 'browser' ? 'open-outline' : 'chevron-forward'">
|
|
||||||
<ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
|
|
||||||
<ion-label>
|
|
||||||
<p class="item-heading">{{item.label}}</p>
|
|
||||||
</ion-label>
|
|
||||||
</ion-item>
|
|
||||||
<ion-item button *ngIf="item.type == 'embedded'" (click)="openItem(item)" [attr.aria-label]="item.label"
|
|
||||||
class="core-moremenu-customitem" detail="true">
|
|
||||||
<ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
|
|
||||||
<ion-label>
|
|
||||||
<p class="item-heading">{{item.label}}</p>
|
|
||||||
</ion-label>
|
|
||||||
</ion-item>
|
|
||||||
</ng-container>
|
|
||||||
<ion-item button *ngIf="showScanQR" (click)="scanQR()" detail="true">
|
|
||||||
<ion-icon name="fas-qrcode" slot="start" aria-hidden="true"></ion-icon>
|
|
||||||
<ion-label>
|
|
||||||
<p class="item-heading">{{ 'core.scanqr' | translate }}</p>
|
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item button *ngIf="showWeb && siteInfo" [href]="siteInfo.siteurl" core-link autoLogin="yes"
|
</ng-container>
|
||||||
[attr.aria-label]="'core.mainmenu.website' | translate" detail="true" detailIcon="open-outline">
|
<ion-item button *ngIf="showScanQR" (click)="scanQR()" detail="true">
|
||||||
<ion-icon name="fas-globe" slot="start" aria-hidden="true"></ion-icon>
|
<ion-icon name="fas-qrcode" slot="start" aria-hidden="true"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<p class="item-heading">{{ 'core.mainmenu.website' | translate }}</p>
|
<p class="item-heading">{{ 'core.scanqr' | translate }}</p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item button *ngIf="showHelp" [href]="docsUrl" core-link autoLogin="no"
|
<ion-item button *ngIf="showWeb && siteInfo" [href]="siteInfo.siteurl" core-link autoLogin="yes"
|
||||||
[attr.aria-label]="'core.mainmenu.help' | translate" detail="true" detailIcon="open-outline">
|
[attr.aria-label]="'core.mainmenu.website' | translate" detail="true" detailIcon="open-outline">
|
||||||
<ion-icon name="far-life-ring" slot="start" aria-hidden="true"></ion-icon>
|
<ion-icon name="fas-globe" slot="start" aria-hidden="true"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<p class="item-heading">{{ 'core.mainmenu.help' | translate }}</p>
|
<p class="item-heading">{{ 'core.mainmenu.website' | translate }}</p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item button (click)="openPreferences()" [attr.aria-label]="'core.settings.preferences' | translate" detail="true">
|
<ion-item button *ngIf="showHelp" [href]="docsUrl" core-link autoLogin="no"
|
||||||
<ion-icon name="fas-wrench" slot="start" aria-hidden="true"></ion-icon>
|
[attr.aria-label]="'core.mainmenu.help' | translate" detail="true" detailIcon="open-outline">
|
||||||
<ion-label>
|
<ion-icon name="far-life-ring" slot="start" aria-hidden="true"></ion-icon>
|
||||||
<p class="item-heading">{{ 'core.settings.preferences' | translate }}</p>
|
<ion-label>
|
||||||
</ion-label>
|
<p class="item-heading">{{ 'core.mainmenu.help' | translate }}</p>
|
||||||
</ion-item>
|
</ion-label>
|
||||||
<ion-item button (click)="logout()" [attr.aria-label]="logoutLabel | translate" detail="true">
|
</ion-item>
|
||||||
<ion-icon name="fas-sign-out-alt" slot="start" aria-hidden="true"></ion-icon>
|
</ion-list>
|
||||||
<ion-label>
|
|
||||||
<p class="item-heading">{{ logoutLabel | translate }}</p>
|
|
||||||
</ion-label>
|
|
||||||
</ion-item>
|
|
||||||
<core-spacer></core-spacer>
|
|
||||||
<ion-item button (click)="openSettings()" [attr.aria-label]="'core.settings.appsettings' | translate" detail="true">
|
|
||||||
<ion-icon name="fas-cogs" slot="start" aria-hidden="true"></ion-icon>
|
|
||||||
<ion-label>
|
|
||||||
<p class="item-heading">{{ 'core.settings.appsettings' | translate }}</p>
|
|
||||||
</ion-label>
|
|
||||||
</ion-item>
|
|
||||||
</ion-list>
|
|
||||||
</core-loading>
|
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
<ion-footer>
|
||||||
|
<ion-item button (click)="openSettings()" [attr.aria-label]="'core.settings.appsettings' | translate" detail="true">
|
||||||
|
<ion-icon name="fas-cogs" slot="start" aria-hidden="true"></ion-icon>
|
||||||
|
<ion-label>
|
||||||
|
<p class="item-heading">{{ 'core.settings.appsettings' | translate }}</p>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
</ion-footer>
|
||||||
|
|
|
@ -19,10 +19,12 @@ import { CoreSharedModule } from '@/core/shared.module';
|
||||||
import { CoreMainMenuMorePage } from './more';
|
import { CoreMainMenuMorePage } from './more';
|
||||||
import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module';
|
import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module';
|
||||||
import { CoreMainMenuProvider } from '@features/mainmenu/services/mainmenu';
|
import { CoreMainMenuProvider } from '@features/mainmenu/services/mainmenu';
|
||||||
|
import { CoreMainMenuComponentsModule } from '@features/mainmenu/components/components.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
CoreSharedModule,
|
CoreSharedModule,
|
||||||
|
CoreMainMenuComponentsModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,21 +17,3 @@ ion-item {
|
||||||
color: var(--core-more-icon, inherit);
|
color: var(--core-more-icon, inherit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@if ($core-more-hide-siteinfo) {
|
|
||||||
.core-moremenu-siteinfo {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@if ($core-more-hide-sitename) {
|
|
||||||
.core-moremenu-sitename {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@if ($core-more-hide-siteurl) {
|
|
||||||
.core-moremenu-siteurl {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ import { Subscription } from 'rxjs';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreSiteInfo } from '@classes/site';
|
import { CoreSiteInfo } from '@classes/site';
|
||||||
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
|
||||||
import { CoreMainMenuDelegate, CoreMainMenuHandlerData } from '../../services/mainmenu-delegate';
|
import { CoreMainMenuDelegate, CoreMainMenuHandlerData } from '../../services/mainmenu-delegate';
|
||||||
import { CoreMainMenu, CoreMainMenuCustomItem } from '../../services/mainmenu';
|
import { CoreMainMenu, CoreMainMenuCustomItem } from '../../services/mainmenu';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
|
@ -39,19 +38,16 @@ import { Translate } from '@singletons';
|
||||||
export class CoreMainMenuMorePage implements OnInit, OnDestroy {
|
export class CoreMainMenuMorePage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
handlers?: CoreMainMenuHandlerData[];
|
handlers?: CoreMainMenuHandlerData[];
|
||||||
allHandlers?: CoreMainMenuHandlerData[];
|
|
||||||
handlersLoaded = false;
|
handlersLoaded = false;
|
||||||
siteInfo?: CoreSiteInfo;
|
siteInfo?: CoreSiteInfo;
|
||||||
siteName?: string;
|
siteName?: string;
|
||||||
logoutLabel = 'core.mainmenu.changesite';
|
|
||||||
showScanQR: boolean;
|
showScanQR: boolean;
|
||||||
showWeb?: boolean;
|
showWeb?: boolean;
|
||||||
showHelp?: boolean;
|
showHelp?: boolean;
|
||||||
docsUrl?: string;
|
docsUrl?: string;
|
||||||
customItems?: CoreMainMenuCustomItem[];
|
customItems?: CoreMainMenuCustomItem[];
|
||||||
siteUrl?: string;
|
|
||||||
loggedOut = false;
|
|
||||||
|
|
||||||
|
protected allHandlers?: CoreMainMenuHandlerData[];
|
||||||
protected subscription!: Subscription;
|
protected subscription!: Subscription;
|
||||||
protected langObserver: CoreEventObserver;
|
protected langObserver: CoreEventObserver;
|
||||||
protected updateSiteObserver: CoreEventObserver;
|
protected updateSiteObserver: CoreEventObserver;
|
||||||
|
@ -70,7 +66,7 @@ export class CoreMainMenuMorePage implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize component.
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
// Load the handlers.
|
// Load the handlers.
|
||||||
|
@ -84,7 +80,7 @@ export class CoreMainMenuMorePage implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page destroyed.
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
window.removeEventListener('resize', this.initHandlers.bind(this));
|
window.removeEventListener('resize', this.initHandlers.bind(this));
|
||||||
|
@ -116,16 +112,10 @@ export class CoreMainMenuMorePage implements OnInit, OnDestroy {
|
||||||
* Load the site info required by the view.
|
* Load the site info required by the view.
|
||||||
*/
|
*/
|
||||||
protected async loadSiteInfo(): Promise<void> {
|
protected async loadSiteInfo(): Promise<void> {
|
||||||
const currentSite = CoreSites.getCurrentSite();
|
const currentSite = CoreSites.getRequiredCurrentSite();
|
||||||
|
|
||||||
if (!currentSite) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.siteInfo = currentSite.getInfo();
|
this.siteInfo = currentSite.getInfo();
|
||||||
this.siteName = currentSite.getSiteName();
|
this.siteName = currentSite.getSiteName();
|
||||||
this.siteUrl = currentSite.getURL();
|
|
||||||
this.logoutLabel = CoreLoginHelper.getLogoutLabel(currentSite);
|
|
||||||
this.showWeb = !currentSite.isFeatureDisabled('CoreMainMenuDelegate_website');
|
this.showWeb = !currentSite.isFeatureDisabled('CoreMainMenuDelegate_website');
|
||||||
this.showHelp = !currentSite.isFeatureDisabled('CoreMainMenuDelegate_help');
|
this.showHelp = !currentSite.isFeatureDisabled('CoreMainMenuDelegate_help');
|
||||||
|
|
||||||
|
@ -154,13 +144,6 @@ export class CoreMainMenuMorePage implements OnInit, OnDestroy {
|
||||||
CoreNavigator.navigateToSitePath('viewer/iframe', { params: { title: item.label, url: item.url } });
|
CoreNavigator.navigateToSitePath('viewer/iframe', { params: { title: item.label, url: item.url } });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Open preferences.
|
|
||||||
*/
|
|
||||||
openPreferences(): void {
|
|
||||||
CoreNavigator.navigateToSitePath('preferences');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open settings.
|
* Open settings.
|
||||||
*/
|
*/
|
||||||
|
@ -200,12 +183,4 @@ export class CoreMainMenuMorePage implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Logout the user.
|
|
||||||
*/
|
|
||||||
logout(): void {
|
|
||||||
this.loggedOut = true;
|
|
||||||
CoreSites.logout();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"address": "Address",
|
"address": "Address",
|
||||||
|
"account": "Account",
|
||||||
"city": "City/town",
|
"city": "City/town",
|
||||||
"contact": "Contact",
|
"contact": "Contact",
|
||||||
"country": "Country",
|
"country": "Country",
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
"interests": "Interests",
|
"interests": "Interests",
|
||||||
"lastname": "Surname",
|
"lastname": "Surname",
|
||||||
"manager": "Manager",
|
"manager": "Manager",
|
||||||
|
"myprofile": "My profile",
|
||||||
"newpicture": "New picture",
|
"newpicture": "New picture",
|
||||||
"noparticipants": "No participants found for this course",
|
"noparticipants": "No participants found for this course",
|
||||||
"participants": "Participants",
|
"participants": "Participants",
|
||||||
|
|
|
@ -127,7 +127,15 @@ $core-login-loading-color-dark: $text-color-dark !default;
|
||||||
$core-login-hide-forgot-password: false !default;
|
$core-login-hide-forgot-password: false !default;
|
||||||
$core-login-hide-need-help: false !default;
|
$core-login-hide-need-help: false !default;
|
||||||
|
|
||||||
// Configuration options for more page.
|
// Configuration options for more page. (deprecated on 4.0)
|
||||||
$core-more-hide-siteinfo: false !default;
|
$core-more-hide-siteinfo: false !default;
|
||||||
$core-more-hide-sitename: false !default;
|
$core-more-hide-sitename: false !default;
|
||||||
$core-more-hide-siteurl: false !default;
|
$core-more-hide-siteurl: false !default;
|
||||||
|
|
||||||
|
// Configuration options for user page.
|
||||||
|
$core-user-hide-siteinfo: $core-more-hide-siteinfo !default;
|
||||||
|
$core-user-hide-sitename: $core-more-hide-sitename !default;
|
||||||
|
$core-user-hide-siteurl: $core-more-hide-siteurl !default;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue