From d4ee108040111f865fde572d85e43347f5b0db22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 28 Jan 2020 15:23:00 +0100 Subject: [PATCH] MOBILE-3325 settings: Move space usage onto site settings --- src/core/settings/pages/site/site.html | 55 +++-- src/core/settings/pages/site/site.module.ts | 2 + src/core/settings/pages/site/site.ts | 65 +++++- .../pages/space-usage/space-usage.html | 10 +- .../settings/pages/space-usage/space-usage.ts | 189 ++++-------------- src/core/settings/providers/helper.ts | 142 ++++++++++++- 6 files changed, 286 insertions(+), 177 deletions(-) diff --git a/src/core/settings/pages/site/site.html b/src/core/settings/pages/site/site.html index 9408eb1c1..ba1879057 100644 --- a/src/core/settings/pages/site/site.html +++ b/src/core/settings/pages/site/site.html @@ -7,24 +7,43 @@ - - - -

{{ 'core.settings.spaceusage' | translate }}

-
- - -

{{ 'core.settings.synchronization' | translate }}

-
- - -

{{ 'core.sharedfiles.sharedfiles' | translate }}

-
+ + + + + + + +

{{siteInfo.fullname}}

+ + {{ siteUrl }} +
- - -

{{ handler.title | translate}}

-
-
+ + +

{{ 'core.settings.spaceusage' | translate }}

+
+

{{ spaceUsage.spaceUsage | coreBytesToSize }}

+

{{ 'core.settings.entriesincache' | translate: { $a: spaceUsage.cacheEntries } }}

+
+ +
+ + +

{{ 'core.settings.synchronization' | translate }}

+
+ + +

{{ 'core.sharedfiles.sharedfiles' | translate }}

+
+ + + +

{{ handler.title | translate}}

+
+
+
diff --git a/src/core/settings/pages/site/site.module.ts b/src/core/settings/pages/site/site.module.ts index f085cea30..753dcbf37 100644 --- a/src/core/settings/pages/site/site.module.ts +++ b/src/core/settings/pages/site/site.module.ts @@ -18,6 +18,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { CoreSiteSettingsPage } from './site'; import { CoreComponentsModule } from '@components/components.module'; import { CoreDirectivesModule } from '@directives/directives.module'; +import { CorePipesModule } from '@pipes/pipes.module'; @NgModule({ declarations: [ @@ -26,6 +27,7 @@ import { CoreDirectivesModule } from '@directives/directives.module'; imports: [ CoreComponentsModule, CoreDirectivesModule, + CorePipesModule, IonicPageModule.forChild(CoreSiteSettingsPage), TranslateModule.forChild() ], diff --git a/src/core/settings/pages/site/site.ts b/src/core/settings/pages/site/site.ts index 9924b3182..5517736af 100644 --- a/src/core/settings/pages/site/site.ts +++ b/src/core/settings/pages/site/site.ts @@ -15,6 +15,9 @@ import { Component, ViewChild } from '@angular/core'; import { IonicPage, NavParams, Platform } from 'ionic-angular'; import { CoreSettingsDelegate, CoreSettingsHandlerData } from '../../providers/delegate'; +import { CoreSite } from '@classes/site'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreSettingsHelper, CoreSiteSpaceUsage } from '../../providers/helper'; import { CoreSplitViewComponent } from '@components/split-view/split-view'; /** @@ -31,24 +34,78 @@ export class CoreSiteSettingsPage { handlers: CoreSettingsHandlerData[]; isIOS: boolean; selectedPage: string; + currentSite: CoreSite; + siteInfo: any; + siteName: string; + siteUrl: string; + spaceUsage: CoreSiteSpaceUsage = { + cacheEntries: 0, + spaceUsage: 0 + }; + loaded = false; + + constructor(protected settingsDelegate: CoreSettingsDelegate, + protected settingsHelper: CoreSettingsHelper, + protected sitesProvider: CoreSitesProvider, + platorm: Platform, + navParams: NavParams) { - constructor(private settingsDelegate: CoreSettingsDelegate, platorm: Platform, navParams: NavParams) { this.isIOS = platorm.is('ios'); this.selectedPage = navParams.get('page') || false; + } /** * View loaded. */ ionViewDidLoad(): void { - this.handlers = this.settingsDelegate.getHandlers(); + this.fetchData().finally(() => { + this.loaded = true; + }); + if (this.selectedPage) { this.openHandler(this.selectedPage); - } else if (this.splitviewCtrl.isOn()) { - this.openHandler('CoreSettingsGeneralPage'); } + } + /** + * View loaded. + */ + protected async fetchData(): Promise { + this.handlers = this.settingsDelegate.getHandlers(); + this.currentSite = this.sitesProvider.getCurrentSite(); + this.siteInfo = this.currentSite.getInfo(); + this.siteName = this.currentSite.getSiteName(); + this.siteUrl = this.currentSite.getURL(); + + return this.settingsHelper.getSiteSpaceUsage(this.sitesProvider.getCurrentSiteId()).then((spaceUsage) => { + this.spaceUsage = spaceUsage; + }); + } + + /** + * Refresh the data. + * + * @param refresher Refresher. + */ + refreshData(refresher: any): void { + this.fetchData().finally(() => { + refresher.complete(); + }); + } + + /** + * Deletes files of a site and the tables that can be cleared. + * + * @param siteData Site object with space usage. + */ + deleteSiteStorage(): void { + this.settingsHelper.deleteSiteStorage(this.currentSite.getSiteName(), this.currentSite.getId()).then((newInfo) => { + this.spaceUsage = newInfo; + }).catch(() => { + // Ignore cancelled confirmation modal. + }); } /** diff --git a/src/core/settings/pages/space-usage/space-usage.html b/src/core/settings/pages/space-usage/space-usage.html index f4d247a89..27c950fb0 100644 --- a/src/core/settings/pages/space-usage/space-usage.html +++ b/src/core/settings/pages/space-usage/space-usage.html @@ -4,10 +4,10 @@ - + - +

{{ site.fullName }}

@@ -19,11 +19,11 @@
- +

{{ 'core.settings.total' | translate }}

-

{{ totalUsage | coreBytesToSize }}

-

{{ 'core.settings.entriesincache' | translate: { $a: totalEntries } }}

+

{{ totals.spaceUsage | coreBytesToSize }}

+

{{ 'core.settings.entriesincache' | translate: { $a: totals.cacheEntries } }}

diff --git a/src/core/settings/pages/space-usage/space-usage.ts b/src/core/settings/pages/space-usage/space-usage.ts index 8b8254837..3e6a74be2 100644 --- a/src/core/settings/pages/space-usage/space-usage.ts +++ b/src/core/settings/pages/space-usage/space-usage.ts @@ -14,15 +14,8 @@ import { Component, } from '@angular/core'; import { IonicPage } from 'ionic-angular'; -import { TranslateService } from '@ngx-translate/core'; -import { CoreAppProvider } from '@providers/app'; -import { CoreEventsProvider } from '@providers/events'; -import { CoreFilepoolProvider } from '@providers/filepool'; -import { CoreSitesProvider } from '@providers/sites'; -import { CoreDomUtilsProvider } from '@providers/utils/dom'; -import { CoreCourseProvider } from '@core/course/providers/course'; -import { CoreFilterProvider } from '@core/filter/providers/filter'; -import { CoreSite } from '@classes/site'; +import { CoreSitesProvider, CoreSiteBasicInfo } from '@providers/sites'; +import { CoreSettingsHelper, CoreSiteSpaceUsage } from '../../providers/helper'; /** * Page that displays the space usage settings. @@ -34,20 +27,16 @@ import { CoreSite } from '@classes/site'; }) export class CoreSettingsSpaceUsagePage { - usageLoaded = false; + loaded = false; sites = []; currentSiteId = ''; - totalUsage = 0; - totalEntries = 0; + totals: CoreSiteSpaceUsage = { + cacheEntries: 0, + spaceUsage: 0 + }; - constructor(private filePoolProvider: CoreFilepoolProvider, - private eventsProvider: CoreEventsProvider, - private sitesProvider: CoreSitesProvider, - private filterProvider: CoreFilterProvider, - private translate: TranslateService, - private domUtils: CoreDomUtilsProvider, - appProvider: CoreAppProvider, - private courseProvider: CoreCourseProvider) { + constructor(protected sitesProvider: CoreSitesProvider, + protected settingsHelper: CoreSettingsHelper) { this.currentSiteId = this.sitesProvider.getCurrentSiteId(); } @@ -55,8 +44,8 @@ export class CoreSettingsSpaceUsagePage { * View loaded. */ ionViewDidLoad(): void { - this.fetchData().finally(() => { - this.usageLoaded = true; + this.calculateSizeUsage().finally(() => { + this.loaded = true; }); } @@ -65,154 +54,62 @@ export class CoreSettingsSpaceUsagePage { * * @return Resolved when done. */ - protected calculateSizeUsage(): Promise { + protected async calculateSizeUsage(): Promise { + // Calculate total usage. + let totalSize = 0, + totalEntries = 0; + return this.sitesProvider.getSortedSites().then((sites) => { this.sites = sites; // Get space usage. - const promises = this.sites.map((siteEntry) => { - return this.sitesProvider.getSite(siteEntry.id).then((site) => { - const proms2 = []; + return Promise.all(this.sites.map((site) => { + return this.settingsHelper.getSiteSpaceUsage(site.id).then((siteInfo) => { + site.cacheEntries = siteInfo.cacheEntries; + site.spaceUsage = siteInfo.spaceUsage; - proms2.push(this.calcSiteClearRows(site).then((rows) => { - siteEntry.cacheEntries = rows; - })); - - proms2.push(site.getSpaceUsage().then((size) => { - siteEntry.spaceUsage = size; - })); - - return Promise.all(proms2); + totalSize += (site.spaceUsage ? parseInt(site.spaceUsage, 10) : 0); + totalEntries += (site.cacheEntries ? parseInt(site.cacheEntries, 10) : 0); }); - }); - - return Promise.all(promises); + })); + }).then(() => { + this.totals.spaceUsage = totalSize; + this.totals.cacheEntries = totalEntries; }); } - /** - * Convenience function to calculate total usage. - */ - protected calculateTotalUsage(): void { - let totalSize = 0, - totalEntries = 0; - this.sites.forEach((site) => { - totalSize += (site.spaceUsage ? parseInt(site.spaceUsage, 10) : 0); - totalEntries += (site.cacheEntries ? parseInt(site.cacheEntries, 10) : 0); - }); - this.totalUsage = totalSize; - this.totalEntries = totalEntries; - } - - /** - * Convenience function to calculate space usage. - * - * @return Resolved when done. - */ - protected fetchData(): Promise { - const promises = [ - this.calculateSizeUsage().then(() => this.calculateTotalUsage()), - ]; - - return Promise.all(promises); - } - /** * Refresh the data. * * @param refresher Refresher. */ refreshData(refresher: any): void { - this.fetchData().finally(() => { + this.calculateSizeUsage().finally(() => { refresher.complete(); }); } - /** - * Convenience function to update site size, along with total usage. - * - * @param site Site object with space usage. - * @param newUsage New space usage of the site in bytes. - */ - protected updateSiteUsage(site: any, newUsage: number): void { - const oldUsage = site.spaceUsage; - site.spaceUsage = newUsage; - this.totalUsage -= oldUsage - newUsage; - } - - /** - * Calculate the number of rows to be deleted on a site. - * - * @param site Site object. - * @return If there are rows to delete or not. - */ - protected calcSiteClearRows(site: CoreSite): Promise { - const clearTables = this.sitesProvider.getSiteTableSchemasToClear(site); - - let totalEntries = 0; - - const promises = clearTables.map((name) => { - return site.getDb().countRecords(name).then((rows) => { - totalEntries += rows; - }); - }); - - return Promise.all(promises).then(() => { - return totalEntries; - }); - } - /** * Deletes files of a site and the tables that can be cleared. * * @param siteData Site object with space usage. */ - deleteSiteStorage(siteData: any): void { - this.filterProvider.formatText(siteData.siteName, {clean: true, singleLine: true, filter: false}, [], siteData.id) - .then((siteName) => { - - const title = this.translate.instant('core.settings.deletesitefilestitle'); - const message = this.translate.instant('core.settings.deletesitefiles', {sitename: siteName}); - - this.domUtils.showConfirm(message, title).then(() => { - return this.sitesProvider.getSite(siteData.id); - }).then((site) => { - - // Clear cache tables. - const cleanSchemas = this.sitesProvider.getSiteTableSchemasToClear(site); - const promises = cleanSchemas.map((name) => { - return site.getDb().deleteRecords(name); - }); - - promises.push(site.deleteFolder().then(() => { - this.filePoolProvider.clearAllPackagesStatus(site.id); - this.filePoolProvider.clearFilepool(site.id); - this.updateSiteUsage(siteData, 0); - this.courseProvider.clearAllCoursesStatus(site.id); - }).catch((error) => { - if (error && error.code === FileError.NOT_FOUND_ERR) { - // Not found, set size 0. - this.filePoolProvider.clearAllPackagesStatus(site.id); - this.updateSiteUsage(siteData, 0); - } else { - // Error, recalculate the site usage. - this.domUtils.showErrorModal('core.settings.errordeletesitefiles', true); - site.getSpaceUsage().then((size) => { - this.updateSiteUsage(siteData, size); - }); - } - }).finally(() => { - this.eventsProvider.trigger(CoreEventsProvider.SITE_STORAGE_DELETED, {}, site.getId()); - - this.calcSiteClearRows(site).then((rows) => { - siteData.cacheEntries = rows; - }); - })); - - return Promise.all(promises); - }).catch(() => { - // Ignore cancelled confirmation modal. - }); + deleteSiteStorage(siteData: CoreSiteBasicInfoWithUsage): void { + this.settingsHelper.deleteSiteStorage(siteData.siteName, siteData.id).then((newInfo) => { + this.totals.spaceUsage -= siteData.spaceUsage - newInfo.spaceUsage; + this.totals.spaceUsage -= siteData.cacheEntries - newInfo.cacheEntries; + siteData.spaceUsage = newInfo.spaceUsage; + siteData.cacheEntries = newInfo.cacheEntries; + }).catch(() => { + // Ignore cancelled confirmation modal. }); } } + +/** + * Basic site info with space usage and cache entries that can be erased. + */ +export interface CoreSiteBasicInfoWithUsage extends CoreSiteBasicInfo { + cacheEntries?: number; // Number of cached entries that can be cleared. + spaceUsage?: number; // Space used in this site. +} diff --git a/src/core/settings/providers/helper.ts b/src/core/settings/providers/helper.ts index 41b5ddd4d..2a0d698ef 100644 --- a/src/core/settings/providers/helper.ts +++ b/src/core/settings/providers/helper.ts @@ -18,14 +18,26 @@ import { CoreCronDelegate } from '@providers/cron'; import { CoreEventsProvider } from '@providers/events'; import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreLoggerProvider } from '@providers/logger'; +import { CoreSite } from '@classes/site'; import { CoreSitesProvider } from '@providers/sites'; import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreConstants } from '@core/constants'; import { CoreConfigProvider } from '@providers/config'; +import { CoreFilterProvider } from '@core/filter/providers/filter'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreConfigConstants } from '../../../configconstants'; import { TranslateService } from '@ngx-translate/core'; import { CoreSite } from '@classes/site'; +/** + * Object with space usage and cache entries that can be erased. + */ +export interface CoreSiteSpaceUsage { + cacheEntries?: number; // Number of cached entries that can be cleared. + spaceUsage?: number; // Space used in this site. +} + /** * Settings helper service. */ @@ -34,10 +46,18 @@ export class CoreSettingsHelper { protected logger; protected syncPromises = {}; - constructor(loggerProvider: CoreLoggerProvider, private appProvider: CoreAppProvider, private cronDelegate: CoreCronDelegate, - private eventsProvider: CoreEventsProvider, private filePoolProvider: CoreFilepoolProvider, - private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider, private translate: TranslateService, - private configProvider: CoreConfigProvider) { + constructor(loggerProvider: CoreLoggerProvider, + protected appProvider: CoreAppProvider, + protected cronDelegate: CoreCronDelegate, + protected domUtils: CoreDomUtilsProvider, + protected eventsProvider: CoreEventsProvider, + protected filePoolProvider: CoreFilepoolProvider, + protected sitesProvider: CoreSitesProvider, + protected utils: CoreUtilsProvider, + protected translate: TranslateService, + protected configProvider: CoreConfigProvider, + protected filterProvider: CoreFilterProvider, + protected courseProvider: CoreCourseProvider) { this.logger = loggerProvider.getInstance('CoreSettingsHelper'); if (!CoreConfigConstants.forceColorScheme) { @@ -63,6 +83,120 @@ export class CoreSettingsHelper { } } + /** + * Deletes files of a site and the tables that can be cleared. + * + * @param siteName Site Name. + * @param siteId: Site ID. + * @return Resolved with detailed new info when done. + */ + async deleteSiteStorage(siteName: string, siteId: string): Promise { + const siteInfo: CoreSiteSpaceUsage = { + cacheEntries: 0, + spaceUsage: 0 + }; + + return this.filterProvider.formatText(siteName, {clean: true, singleLine: true, filter: false}, [], siteId) + .then((siteName) => { + + const title = this.translate.instant('core.settings.deletesitefilestitle'); + const message = this.translate.instant('core.settings.deletesitefiles', {sitename: siteName}); + + return this.domUtils.showConfirm(message, title).then(() => { + return this.sitesProvider.getSite(siteId); + }).then((site) => { + + // Clear cache tables. + const cleanSchemas = this.sitesProvider.getSiteTableSchemasToClear(); + const promises = cleanSchemas.map((name) => { + return site.getDb().deleteRecords(name); + }); + + promises.push(site.deleteFolder().then(() => { + this.filePoolProvider.clearAllPackagesStatus(site.id); + this.filePoolProvider.clearFilepool(site.id); + this.courseProvider.clearAllCoursesStatus(site.id); + + siteInfo.spaceUsage = 0; + }).catch((error) => { + if (error && error.code === FileError.NOT_FOUND_ERR) { + // Not found, set size 0. + this.filePoolProvider.clearAllPackagesStatus(site.id); + siteInfo.spaceUsage = 0; + } else { + // Error, recalculate the site usage. + this.domUtils.showErrorModal('core.settings.errordeletesitefiles', true); + + return site.getSpaceUsage().then((size) => { + siteInfo.spaceUsage = size; + }); + } + }).then(() => { + this.eventsProvider.trigger(CoreEventsProvider.SITE_STORAGE_DELETED, {}, site.getId()); + + return this.calcSiteClearRows(site).then((rows) => { + siteInfo.cacheEntries = rows; + }); + })); + + return Promise.all(promises).then(() => { + return siteInfo; + }); + }); + }); + } + + /** + * Calculates each site's usage, and the total usage. + * + * @param siteId ID of the site. Current site if undefined. + * @return Resolved with detailed info when done. + */ + async getSiteSpaceUsage(siteId?: string): Promise { + return this.sitesProvider.getSite(siteId).then((site) => { + // Get space usage. + const promises = []; + const siteInfo: CoreSiteSpaceUsage = { + cacheEntries: 0, + spaceUsage: 0 + }; + + promises.push(this.calcSiteClearRows(site).then((rows) => { + siteInfo.cacheEntries = rows; + })); + + promises.push(site.getSpaceUsage().then((size) => { + siteInfo.spaceUsage = size; + })); + + return Promise.all(promises).then(() => { + return siteInfo; + }); + }); + } + + /** + * Calculate the number of rows to be deleted on a site. + * + * @param site Site object. + * @return If there are rows to delete or not. + */ + protected async calcSiteClearRows(site: CoreSite): Promise { + const clearTables = this.sitesProvider.getSiteTableSchemasToClear(); + + let totalEntries = 0; + + const promises = clearTables.map((name) => { + return site.getDb().countRecords(name).then((rows) => { + totalEntries += rows; + }); + }); + + return Promise.all(promises).then(() => { + return totalEntries; + }); + } + /** * Get a certain processor from a list of processors. *