MOBILE-3565 settings: Add site preferences
parent
d6a42f992b
commit
adf5de823f
|
@ -70,7 +70,8 @@
|
||||||
<h2>{{ 'core.mainmenu.help' | translate }}</h2>
|
<h2>{{ 'core.mainmenu.help' | translate }}</h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item button (click)="openSitePreferences()" title="{{ 'core.settings.preferences' | translate }}" detail>
|
<ion-item button router-direction="forward" routerLink="preferences"
|
||||||
|
title="{{ 'core.settings.preferences' | translate }}" detail>
|
||||||
<ion-icon name="fa-wrench" slot="start"></ion-icon>
|
<ion-icon name="fa-wrench" slot="start"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ 'core.settings.preferences' | translate }}</h2>
|
<h2>{{ 'core.settings.preferences' | translate }}</h2>
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-buttons slot="start">
|
||||||
|
<ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
|
||||||
|
</ion-buttons>
|
||||||
|
<ion-title>{{ 'core.settings.preferences' | translate}}</ion-title>
|
||||||
|
<ion-buttons slot="end">
|
||||||
|
</ion-buttons>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content>
|
||||||
|
<ion-refresher slot="fixed" [disabled]="!loaded" (ionRefresh)="refreshData($event)">
|
||||||
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
|
</ion-refresher>
|
||||||
|
<core-loading [hideUntil]="loaded">
|
||||||
|
<ion-list>
|
||||||
|
<ion-item *ngIf="siteInfo" class="ion-text-wrap">
|
||||||
|
<ion-label>
|
||||||
|
<h2>{{siteInfo!.fullname}}</h2>
|
||||||
|
<p>
|
||||||
|
<core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0"
|
||||||
|
[wsNotFiltered]="true"></core-format-text>
|
||||||
|
</p>
|
||||||
|
<p>{{ siteUrl }}</p>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item-divider></ion-item-divider>
|
||||||
|
<ion-item *ngIf="isIOS"
|
||||||
|
(click)="openHandler('CoreSharedFilesListPage', {manage: true, siteId: siteId, hideSitePicker: true})"
|
||||||
|
[title]="'core.sharedfiles.sharedfiles' | translate"
|
||||||
|
[class.core-split-item-selected]="'CoreSharedFilesListPage' == selectedPage" details>
|
||||||
|
<ion-icon name="fas-folder" slot="start"></ion-icon>
|
||||||
|
<ion-label>
|
||||||
|
<h2>{{ 'core.sharedfiles.sharedfiles' | translate }}</h2>
|
||||||
|
</ion-label>
|
||||||
|
<ion-badge slot="end">{{ iosSharedFiles }}</ion-badge>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item *ngFor="let handler of handlers" [ngClass]="['core-settings-handler', handler.class]"
|
||||||
|
(click)="openHandler(handler.page, handler.params)" [title]="handler.title | translate" details
|
||||||
|
[class.core-split-item-selected]="handler.page == selectedPage">
|
||||||
|
<ion-icon [name]="handler.icon" slot="start" *ngIf="handler.icon">
|
||||||
|
</ion-icon>
|
||||||
|
<ion-label>
|
||||||
|
<h2>{{ handler.title | translate}}</h2>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-card>
|
||||||
|
<ion-item class="ion-text-wrap" *ngIf="spaceUsage">
|
||||||
|
<ion-label>
|
||||||
|
<h2 class="ion-text-wrap">{{ 'core.settings.spaceusage' | translate }} <ion-icon
|
||||||
|
name="fas-info-circle" color="secondary" [attr.aria-label]="'core.info' | translate"
|
||||||
|
(click)="showSpaceInfo()"></ion-icon>
|
||||||
|
</h2>
|
||||||
|
<p *ngIf="spaceUsage.spaceUsage">{{ spaceUsage.spaceUsage | coreBytesToSize }}</p>
|
||||||
|
</ion-label>
|
||||||
|
<ion-button fill="clear" color="danger" slot="end" (click)="deleteSiteStorage()"
|
||||||
|
[hidden]="spaceUsage.spaceUsage! + spaceUsage.cacheEntries! <= 0"
|
||||||
|
[attr.aria-label]="'core.settings.deletesitefilestitle' | translate">
|
||||||
|
<ion-icon name="fas-trash" slot="icon-only"></ion-icon>
|
||||||
|
</ion-button>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item class="ion-text-wrap">
|
||||||
|
<ion-label>
|
||||||
|
<h2>{{ 'core.settings.synchronizenow' | translate }} <ion-icon name="fas-info-circle"
|
||||||
|
color="secondary" [attr.aria-label]="'core.info' | translate" (click)="showSyncInfo()">
|
||||||
|
</ion-icon>
|
||||||
|
</h2>
|
||||||
|
</ion-label>
|
||||||
|
<ion-button fill="clear" slot="end" *ngIf="!isSynchronizing()" (click)="synchronize()"
|
||||||
|
[title]="siteName" [attr.aria-label]="'core.settings.synchronizenow' | translate">
|
||||||
|
<ion-icon name="fas-sync-alt" slot="icon-only"></ion-icon>
|
||||||
|
</ion-button>
|
||||||
|
<ion-spinner slot="end" *ngIf="isSynchronizing()"></ion-spinner>
|
||||||
|
</ion-item>
|
||||||
|
</ion-card>
|
||||||
|
</ion-list>
|
||||||
|
</core-loading>
|
||||||
|
</ion-content>
|
|
@ -0,0 +1,48 @@
|
||||||
|
// (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 { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { IonicModule } from '@ionic/angular';
|
||||||
|
|
||||||
|
import { CoreComponentsModule } from '@components/components.module';
|
||||||
|
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||||
|
import { CorePipesModule } from '@pipes/pipes.module';
|
||||||
|
|
||||||
|
import { CoreSitePreferencesPage } from './site.page';
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: CoreSitePreferencesPage,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
CoreSitePreferencesPage,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
RouterModule.forChild(routes),
|
||||||
|
CommonModule,
|
||||||
|
IonicModule,
|
||||||
|
TranslateModule.forChild(),
|
||||||
|
CoreComponentsModule,
|
||||||
|
CoreDirectivesModule,
|
||||||
|
CorePipesModule,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class CoreSitePreferencesPageModule {}
|
|
@ -0,0 +1,217 @@
|
||||||
|
// (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 { ActivatedRoute, Params, Router } from '@angular/router';
|
||||||
|
import { IonRefresher } from '@ionic/angular';
|
||||||
|
|
||||||
|
import { CoreSettingsDelegate, CoreSettingsHandlerData } from '../../services/settings.delegate';
|
||||||
|
import { CoreEventObserver, CoreEvents, CoreEventSiteUpdatedData } from '@singletons/events';
|
||||||
|
import { CoreSites } from '@services/sites';
|
||||||
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
|
// import { CoreSplitViewComponent } from '@components/split-view/split-view';
|
||||||
|
// import { CoreSharedFiles } from '@core/sharedfiles/providers/sharedfiles';
|
||||||
|
import { CoreSettingsHelper, CoreSiteSpaceUsage } from '../../services/settings.helper';
|
||||||
|
import { CoreApp } from '@services/app';
|
||||||
|
import { CoreSiteInfo } from '@classes/site';
|
||||||
|
import { Translate } from '@singletons/core.singletons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page that displays the list of site settings pages.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'page-core-site-preferences',
|
||||||
|
templateUrl: 'site.html',
|
||||||
|
})
|
||||||
|
export class CoreSitePreferencesPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
// @ViewChild(CoreSplitViewComponent) splitviewCtrl?: CoreSplitViewComponent;
|
||||||
|
|
||||||
|
isIOS: boolean;
|
||||||
|
selectedPage?: string;
|
||||||
|
|
||||||
|
handlers: CoreSettingsHandlerData[] = [];
|
||||||
|
siteId: string;
|
||||||
|
siteInfo?: CoreSiteInfo;
|
||||||
|
siteName?: string;
|
||||||
|
siteUrl?: string;
|
||||||
|
spaceUsage: CoreSiteSpaceUsage = {
|
||||||
|
cacheEntries: 0,
|
||||||
|
spaceUsage: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
loaded = false;
|
||||||
|
iosSharedFiles = 0;
|
||||||
|
protected sitesObserver: CoreEventObserver;
|
||||||
|
protected isDestroyed = false;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected settingsDelegate: CoreSettingsDelegate,
|
||||||
|
protected route: ActivatedRoute,
|
||||||
|
protected router: Router, // Will be removed when splitview is implemented
|
||||||
|
) {
|
||||||
|
|
||||||
|
this.isIOS = CoreApp.instance.isIOS();
|
||||||
|
this.siteId = CoreSites.instance.getCurrentSiteId();
|
||||||
|
|
||||||
|
this.selectedPage = route.snapshot.paramMap.get('page') || undefined;
|
||||||
|
|
||||||
|
this.sitesObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, (data: CoreEventSiteUpdatedData) => {
|
||||||
|
if (data.siteId == this.siteId) {
|
||||||
|
this.refreshData();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View loaded.
|
||||||
|
*/
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.fetchData().finally(() => {
|
||||||
|
this.loaded = true;
|
||||||
|
|
||||||
|
if (this.selectedPage) {
|
||||||
|
this.openHandler(this.selectedPage);
|
||||||
|
} /* else if (this.splitviewCtrl.isOn()) {
|
||||||
|
if (this.isIOS) {
|
||||||
|
this.openHandler('CoreSharedFilesListPage', { manage: true, siteId: this.siteId, hideSitePicker: true });
|
||||||
|
} else if (this.handlers.length > 0) {
|
||||||
|
this.openHandler(this.handlers[0].page, this.handlers[0].params);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch Data.
|
||||||
|
*/
|
||||||
|
protected async fetchData(): Promise<void> {
|
||||||
|
this.handlers = this.settingsDelegate.getHandlers();
|
||||||
|
|
||||||
|
const currentSite = CoreSites.instance.getCurrentSite();
|
||||||
|
this.siteInfo = currentSite!.getInfo();
|
||||||
|
this.siteName = currentSite!.getSiteName();
|
||||||
|
this.siteUrl = currentSite!.getURL();
|
||||||
|
|
||||||
|
const promises: Promise<void>[] = [];
|
||||||
|
|
||||||
|
promises.push(CoreSettingsHelper.instance.getSiteSpaceUsage(this.siteId)
|
||||||
|
.then((spaceUsage) => {
|
||||||
|
this.spaceUsage = spaceUsage;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}));
|
||||||
|
|
||||||
|
/* if (this.isIOS) {
|
||||||
|
promises.push(CoreSharedFiles.instance.getSiteSharedFiles(this.siteId)
|
||||||
|
.then((files) => {
|
||||||
|
this.iosSharedFiles = files.length;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}));
|
||||||
|
}*/
|
||||||
|
|
||||||
|
await Promise.all(promises);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Syncrhonizes the site.
|
||||||
|
*/
|
||||||
|
async synchronize(): Promise<void> {
|
||||||
|
try {
|
||||||
|
// Using syncOnlyOnWifi false to force manual sync.
|
||||||
|
await CoreSettingsHelper.instance.synchronizeSite(false, this.siteId);
|
||||||
|
} catch (error) {
|
||||||
|
if (this.isDestroyed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CoreDomUtils.instance.showErrorModalDefault(error, 'core.settings.errorsyncsite', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if site is beeing synchronized.
|
||||||
|
*
|
||||||
|
* @return True if site is beeing synchronized, false otherwise.
|
||||||
|
*/
|
||||||
|
isSynchronizing(): boolean {
|
||||||
|
return !!CoreSettingsHelper.instance.getSiteSyncPromise(this.siteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh the data.
|
||||||
|
*
|
||||||
|
* @param refresher Refresher.
|
||||||
|
*/
|
||||||
|
refreshData(refresher?: CustomEvent<IonRefresher>): void {
|
||||||
|
this.fetchData().finally(() => {
|
||||||
|
refresher?.detail.complete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes files of a site and the tables that can be cleared.
|
||||||
|
*
|
||||||
|
* @param siteData Site object with space usage.
|
||||||
|
*/
|
||||||
|
async deleteSiteStorage(): Promise<void> {
|
||||||
|
try {
|
||||||
|
this.spaceUsage = await CoreSettingsHelper.instance.deleteSiteStorage(this.siteName || '', this.siteId);
|
||||||
|
} catch {
|
||||||
|
// Ignore cancelled confirmation modal.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a handler.
|
||||||
|
*
|
||||||
|
* @param page Page to open.
|
||||||
|
* @param params Params of the page to open.
|
||||||
|
*/
|
||||||
|
openHandler(page: string, params?: Params): void {
|
||||||
|
this.selectedPage = page;
|
||||||
|
// this.splitviewCtrl.push(page, params);
|
||||||
|
this.router.navigate([page], { relativeTo: this.route, queryParams: params });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show information about space usage actions.
|
||||||
|
*/
|
||||||
|
showSpaceInfo(): void {
|
||||||
|
CoreDomUtils.instance.showAlert(
|
||||||
|
Translate.instance.instant('core.help'),
|
||||||
|
Translate.instance.instant('core.settings.spaceusagehelp'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show information about sync actions.
|
||||||
|
*/
|
||||||
|
showSyncInfo(): void {
|
||||||
|
CoreDomUtils.instance.showAlert(
|
||||||
|
Translate.instance.instant('core.help'),
|
||||||
|
Translate.instance.instant('core.settings.synchronizenowhelp'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page destroyed.
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.isDestroyed = true;
|
||||||
|
this.sitesObserver?.off();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,6 +23,10 @@ const routes: Routes = [
|
||||||
path: 'settings',
|
path: 'settings',
|
||||||
loadChildren: () => import('@core/settings/settings.module').then(m => m.CoreSettingsModule),
|
loadChildren: () => import('@core/settings/settings.module').then(m => m.CoreSettingsModule),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'preferences',
|
||||||
|
loadChildren: () => import('@core/settings/pages/site/site.page.module').then(m => m.CoreSitePreferencesPageModule),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
@ -18,11 +18,11 @@ import { RouterModule, Routes } from '@angular/router';
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: 'about',
|
path: 'about',
|
||||||
loadChildren: () => import('./pages/about/about.page.module').then( m => m.CoreSettingsAboutPageModule),
|
loadChildren: () => import('./pages/about/about.page.module').then(m => m.CoreSettingsAboutPageModule),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'general',
|
path: 'general',
|
||||||
loadChildren: () => import('./pages/general/general.page.module').then( m => m.CoreSettingsGeneralPageModule),
|
loadChildren: () => import('./pages/general/general.page.module').then(m => m.CoreSettingsGeneralPageModule),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'spaceusage',
|
path: 'spaceusage',
|
||||||
|
@ -38,7 +38,7 @@ const routes: Routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
loadChildren: () => import('./pages/app/app.page.module').then( m => m.CoreSettingsAppPageModule),
|
loadChildren: () => import('./pages/app/app.page.module').then(m => m.CoreSettingsAppPageModule),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue