MOBILE-3565 settings: Add site preferences
parent
d6a42f992b
commit
adf5de823f
|
@ -70,7 +70,8 @@
|
|||
<h2>{{ 'core.mainmenu.help' | translate }}</h2>
|
||||
</ion-label>
|
||||
</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-label>
|
||||
<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',
|
||||
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({
|
||||
|
|
Loading…
Reference in New Issue