MOBILE-3608 blocks: Add sitehome and dashboard blocks
parent
7d1d318afc
commit
c3372e8076
|
@ -19,7 +19,7 @@ import { CoreMainMenuHomeRoutingModule } from '@features/mainmenu/pages/home/hom
|
||||||
import { CoreMainMenuHomeDelegate } from '@features/mainmenu/services/home-delegate';
|
import { CoreMainMenuHomeDelegate } from '@features/mainmenu/services/home-delegate';
|
||||||
|
|
||||||
import { CoreDashboardHomeHandler, CoreDashboardHomeHandlerService } from './services/handlers/dashboard-home';
|
import { CoreDashboardHomeHandler, CoreDashboardHomeHandlerService } from './services/handlers/dashboard-home';
|
||||||
import { CoreCoursesMyCoursesHomeHandler, CoreCoursesMyCoursesHomeHandlerService } from './services/handlers/my-courses.home';
|
import { CoreCoursesMyCoursesHomeHandler, CoreCoursesMyCoursesHomeHandlerService } from './services/handlers/my-courses-home';
|
||||||
|
|
||||||
const mainMenuHomeChildrenRoutes: Routes = [
|
const mainMenuHomeChildrenRoutes: Routes = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,8 +12,19 @@
|
||||||
</core-context-menu>
|
</core-context-menu>
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<!-- @todo -->
|
<ion-refresher slot="fixed" [disabled]="!loaded" (ionRefresh)="refreshDashboard($event)">
|
||||||
<core-empty-box icon="fa-home" [message]="'core.courses.nocourses' | translate">
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
<div>Dashboard</div>
|
</ion-refresher>
|
||||||
</core-empty-box>
|
|
||||||
|
<core-loading [hideUntil]="loaded">
|
||||||
|
<ion-list>
|
||||||
|
<ng-container *ngFor="let block of blocks">
|
||||||
|
<core-block *ngIf="block.visible" [block]="block" contextLevel="user" [instanceId]="userId"
|
||||||
|
[extraData]="{'downloadEnabled': downloadEnabled}"></core-block>
|
||||||
|
</ng-container>
|
||||||
|
</ion-list>
|
||||||
|
|
||||||
|
<core-empty-box *ngIf="blocks.length == 0" icon="fas-th-large" [message]="'core.course.nocontentavailable' | translate">
|
||||||
|
</core-empty-box>
|
||||||
|
</core-loading>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
|
@ -20,6 +20,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { CoreComponentsModule } from '@components/components.module';
|
import { CoreComponentsModule } from '@components/components.module';
|
||||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||||
|
import { CoreBlockComponentsModule } from '@features/block/components/components.module';
|
||||||
|
|
||||||
import { CoreCoursesDashboardPage } from './dashboard';
|
import { CoreCoursesDashboardPage } from './dashboard';
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ const routes: Routes = [
|
||||||
TranslateModule.forChild(),
|
TranslateModule.forChild(),
|
||||||
CoreComponentsModule,
|
CoreComponentsModule,
|
||||||
CoreDirectivesModule,
|
CoreDirectivesModule,
|
||||||
|
CoreBlockComponentsModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
CoreCoursesDashboardPage,
|
CoreCoursesDashboardPage,
|
||||||
|
|
|
@ -12,12 +12,16 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit, QueryList, ViewChildren } from '@angular/core';
|
||||||
import { NavController } from '@ionic/angular';
|
import { IonRefresher, NavController } from '@ionic/angular';
|
||||||
|
|
||||||
import { CoreCourses, CoreCoursesProvider } from '../../services/courses';
|
import { CoreCourses, CoreCoursesProvider } from '../../services/courses';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
|
import { CoreCoursesDashboard } from '@features/courses/services/dashboard';
|
||||||
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
|
import { CoreCourseBlock } from '@features/course/services/course';
|
||||||
|
import { CoreBlockComponent } from '@features/block/components/block/block';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays the dashboard page.
|
* Page that displays the dashboard page.
|
||||||
|
@ -29,16 +33,20 @@ import { CoreSites } from '@services/sites';
|
||||||
})
|
})
|
||||||
export class CoreCoursesDashboardPage implements OnInit, OnDestroy {
|
export class CoreCoursesDashboardPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
@ViewChildren(CoreBlockComponent) blocksComponents?: QueryList<CoreBlockComponent>;
|
||||||
|
|
||||||
|
|
||||||
searchEnabled = false;
|
searchEnabled = false;
|
||||||
downloadEnabled = false;
|
downloadEnabled = false;
|
||||||
downloadCourseEnabled = false;
|
downloadCourseEnabled = false;
|
||||||
downloadCoursesEnabled = false;
|
downloadCoursesEnabled = false;
|
||||||
downloadEnabledIcon = 'far-square';
|
downloadEnabledIcon = 'far-square';
|
||||||
|
userId?: number;
|
||||||
|
blocks: Partial<CoreCourseBlock>[] = [];
|
||||||
|
loaded = false;
|
||||||
|
|
||||||
protected updateSiteObserver?: CoreEventObserver;
|
protected updateSiteObserver?: CoreEventObserver;
|
||||||
|
|
||||||
siteName = 'Hello world';
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected navCtrl: NavController,
|
protected navCtrl: NavController,
|
||||||
) { }
|
) { }
|
||||||
|
@ -59,8 +67,82 @@ export class CoreCoursesDashboardPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
this.switchDownload(this.downloadEnabled && this.downloadCourseEnabled && this.downloadCoursesEnabled);
|
this.switchDownload(this.downloadEnabled && this.downloadCourseEnabled && this.downloadCoursesEnabled);
|
||||||
}, CoreSites.instance.getCurrentSiteId());
|
}, CoreSites.instance.getCurrentSiteId());
|
||||||
|
|
||||||
|
this.loadContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience function to fetch the dashboard data.
|
||||||
|
*
|
||||||
|
* @return Promise resolved when done.
|
||||||
|
*/
|
||||||
|
protected async loadContent(): Promise<void> {
|
||||||
|
const available = await CoreCoursesDashboard.instance.isAvailable();
|
||||||
|
|
||||||
|
if (available) {
|
||||||
|
this.userId = CoreSites.instance.getCurrentSiteUserId();
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.blocks = await CoreCoursesDashboard.instance.getDashboardBlocks();
|
||||||
|
} catch (error) {
|
||||||
|
CoreDomUtils.instance.showErrorModal(error);
|
||||||
|
|
||||||
|
// Cannot get the blocks, just show dashboard if needed.
|
||||||
|
this.loadFallbackBlocks();
|
||||||
|
}
|
||||||
|
} else if (!CoreCoursesDashboard.instance.isDisabledInSite()) {
|
||||||
|
// Not available, but not disabled either. Use fallback.
|
||||||
|
this.loadFallbackBlocks();
|
||||||
|
} else {
|
||||||
|
// Disabled.
|
||||||
|
this.blocks = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// this.dashboardEnabled = this.blockDelegate.hasSupportedBlock(this.blocks);
|
||||||
|
this.loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load fallback blocks to shown before 3.6 when dashboard blocks are not supported.
|
||||||
|
*/
|
||||||
|
protected loadFallbackBlocks(): void {
|
||||||
|
this.blocks = [
|
||||||
|
{
|
||||||
|
name: 'myoverview',
|
||||||
|
visible: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'timeline',
|
||||||
|
visible: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh the dashboard data.
|
||||||
|
*
|
||||||
|
* @param refresher Refresher.
|
||||||
|
*/
|
||||||
|
refreshDashboard(refresher: CustomEvent<IonRefresher>): void {
|
||||||
|
const promises: Promise<void>[] = [];
|
||||||
|
|
||||||
|
promises.push(CoreCoursesDashboard.instance.invalidateDashboardBlocks());
|
||||||
|
|
||||||
|
// Invalidate the blocks.
|
||||||
|
this.blocksComponents?.forEach((blockComponent) => {
|
||||||
|
promises.push(blockComponent.invalidate().catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
Promise.all(promises).finally(() => {
|
||||||
|
this.loadContent().finally(() => {
|
||||||
|
refresher?.detail.complete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle download enabled.
|
* Toggle download enabled.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
// (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 { Injectable } from '@angular/core';
|
||||||
|
import { CoreSites } from '@services/sites';
|
||||||
|
import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
|
||||||
|
import { CoreCourseBlock } from '@features/course/services/course';
|
||||||
|
import { CoreStatusWithWarningsWSResponse } from '@services/ws';
|
||||||
|
import { makeSingleton } from '@singletons';
|
||||||
|
|
||||||
|
const ROOT_CACHE_KEY = 'CoreCoursesDashboard:';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service that provides some features regarding course overview.
|
||||||
|
*/
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class CoreCoursesDashboardProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache key for dashboard blocks WS calls.
|
||||||
|
*
|
||||||
|
* @param userId User ID. Default, 0 means current user.
|
||||||
|
* @return Cache key.
|
||||||
|
*/
|
||||||
|
protected getDashboardBlocksCacheKey(userId: number = 0): string {
|
||||||
|
return ROOT_CACHE_KEY + 'blocks:' + userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get dashboard blocks.
|
||||||
|
*
|
||||||
|
* @param userId User ID. Default, current user.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved with the list of blocks.
|
||||||
|
* @since 3.6
|
||||||
|
*/
|
||||||
|
async getDashboardBlocks(userId?: number, siteId?: string): Promise<CoreCourseBlock[]> {
|
||||||
|
const site = await CoreSites.instance.getSite(siteId);
|
||||||
|
|
||||||
|
const params: CoreBlockGetDashboardBlocksWSParams = {
|
||||||
|
returncontents: true,
|
||||||
|
};
|
||||||
|
const preSets: CoreSiteWSPreSets = {
|
||||||
|
cacheKey: this.getDashboardBlocksCacheKey(userId),
|
||||||
|
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
||||||
|
};
|
||||||
|
if (userId) {
|
||||||
|
params.userid = userId;
|
||||||
|
}
|
||||||
|
const result = await site.read<CoreBlockGetDashboardBlocksWSResponse>('core_block_get_dashboard_blocks', params, preSets);
|
||||||
|
|
||||||
|
return result.blocks || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates dashboard blocks WS call.
|
||||||
|
*
|
||||||
|
* @param userId User ID. Default, current user.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved when the data is invalidated.
|
||||||
|
*/
|
||||||
|
async invalidateDashboardBlocks(userId?: number, siteId?: string): Promise<void> {
|
||||||
|
const site = await CoreSites.instance.getSite(siteId);
|
||||||
|
|
||||||
|
return await site.invalidateWsCacheForKey(this.getDashboardBlocksCacheKey(userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not block based Dashboard is available for a certain site.
|
||||||
|
*
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved with true if available, resolved with false or rejected otherwise.
|
||||||
|
* @since 3.6
|
||||||
|
*/
|
||||||
|
async isAvailable(siteId?: string): Promise<boolean> {
|
||||||
|
const site = await CoreSites.instance.getSite(siteId);
|
||||||
|
|
||||||
|
// First check if it's disabled.
|
||||||
|
if (this.isDisabledInSite(site)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return site.wsAvailable('core_block_get_dashboard_blocks');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if Site Home is disabled in a certain site.
|
||||||
|
*
|
||||||
|
* @param siteId Site Id. If not defined, use current site.
|
||||||
|
* @return Promise resolved with true if disabled, rejected or resolved with false otherwise.
|
||||||
|
*/
|
||||||
|
async isDisabled(siteId?: string): Promise<boolean> {
|
||||||
|
const site = await CoreSites.instance.getSite(siteId);
|
||||||
|
|
||||||
|
return this.isDisabledInSite(site);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if Site Home is disabled in a certain site.
|
||||||
|
*
|
||||||
|
* @param site Site. If not defined, use current site.
|
||||||
|
* @return Whether it's disabled.
|
||||||
|
*/
|
||||||
|
isDisabledInSite(site?: CoreSite): boolean {
|
||||||
|
site = site || CoreSites.instance.getCurrentSite();
|
||||||
|
|
||||||
|
return !!site?.isFeatureDisabled('CoreMainMenuDelegate_CoreCoursesDashboard');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CoreCoursesDashboard extends makeSingleton(CoreCoursesDashboardProvider) {}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params of core_block_get_dashboard_blocks WS.
|
||||||
|
*/
|
||||||
|
type CoreBlockGetDashboardBlocksWSParams = {
|
||||||
|
userid?: number; // User id (optional), default is current user.
|
||||||
|
returncontents?: boolean; // Whether to return the block contents.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data returned by core_block_get_dashboard_blocks WS.
|
||||||
|
*/
|
||||||
|
type CoreBlockGetDashboardBlocksWSResponse = {
|
||||||
|
blocks: CoreCourseBlock[]; // List of blocks in the course.
|
||||||
|
warnings?: CoreStatusWithWarningsWSResponse[];
|
||||||
|
};
|
|
@ -13,8 +13,10 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
|
||||||
import { CoreMainMenuHomeHandler, CoreMainMenuHomeHandlerToDisplay } from '@features/mainmenu/services/home-delegate';
|
import { CoreMainMenuHomeHandler, CoreMainMenuHomeHandlerToDisplay } from '@features/mainmenu/services/home-delegate';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { CoreCoursesDashboard } from '../dashboard';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to add dashboard into home page.
|
* Handler to add dashboard into home page.
|
||||||
|
@ -42,10 +44,10 @@ export class CoreDashboardHomeHandlerService implements CoreMainMenuHomeHandler
|
||||||
* @param siteId Site ID. If not defined, current site.
|
* @param siteId Site ID. If not defined, current site.
|
||||||
* @return Whether or not the handler is enabled on a site level.
|
* @return Whether or not the handler is enabled on a site level.
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
async isEnabledForSite(siteId?: string): Promise<boolean> {
|
async isEnabledForSite(siteId?: string): Promise<boolean> {
|
||||||
// @todo return this.blockDelegate.hasSupportedBlock(this.blocks);
|
const blocks = await CoreCoursesDashboard.instance.getDashboardBlocks(undefined, siteId);
|
||||||
return true;
|
|
||||||
|
return CoreBlockDelegate.instance.hasSupportedBlock(blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,8 +13,11 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
|
||||||
import { CoreMainMenuHomeHandler, CoreMainMenuHomeHandlerToDisplay } from '@features/mainmenu/services/home-delegate';
|
import { CoreMainMenuHomeHandler, CoreMainMenuHomeHandlerToDisplay } from '@features/mainmenu/services/home-delegate';
|
||||||
|
import { CoreSiteHome } from '@features/sitehome/services/sitehome';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { CoreCoursesDashboard } from '../dashboard';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to add my courses into home page.
|
* Handler to add my courses into home page.
|
||||||
|
@ -42,10 +45,10 @@ export class CoreCoursesMyCoursesHomeHandlerService implements CoreMainMenuHomeH
|
||||||
* @param siteId Site ID. If not defined, current site.
|
* @param siteId Site ID. If not defined, current site.
|
||||||
* @return Whether or not the handler is enabled on a site level.
|
* @return Whether or not the handler is enabled on a site level.
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
async isEnabledForSite(siteId?: string): Promise<boolean> {
|
async isEnabledForSite(siteId?: string): Promise<boolean> {
|
||||||
// @todo return !this.blockDelegate.hasSupportedBlock(this.blocks) && !CoreSiteHome.instance.isAvailable(siteId);
|
const blocks = await CoreCoursesDashboard.instance.getDashboardBlocks(undefined, siteId);
|
||||||
return true;
|
|
||||||
|
return !CoreBlockDelegate.instance.hasSupportedBlock(blocks)&& !CoreSiteHome.instance.isAvailable(siteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { IonRefresher, NavController } from '@ionic/angular';
|
import { IonRefresher, NavController } from '@ionic/angular';
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import { CoreSiteHome } from '@features/sitehome/services/sitehome';
|
||||||
import { CoreCourses, CoreCoursesProvider } from '@features//courses/services/courses';
|
import { CoreCourses, CoreCoursesProvider } from '@features//courses/services/courses';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
import { CoreCourseHelper } from '@features/course/services/course-helper';
|
import { CoreCourseHelper } from '@features/course/services/course-helper';
|
||||||
|
import { CoreBlockCourseBlocksComponent } from '@features/block/components/course-blocks/course-blocks';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays site home index.
|
* Page that displays site home index.
|
||||||
|
@ -34,7 +35,7 @@ import { CoreCourseHelper } from '@features/course/services/course-helper';
|
||||||
})
|
})
|
||||||
export class CoreSiteHomeIndexPage implements OnInit, OnDestroy {
|
export class CoreSiteHomeIndexPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
// @todo @ViewChild(CoreBlockCourseBlocksComponent) courseBlocksComponent: CoreBlockCourseBlocksComponent;
|
@ViewChild(CoreBlockCourseBlocksComponent) courseBlocksComponent?: CoreBlockCourseBlocksComponent;
|
||||||
|
|
||||||
dataLoaded = false;
|
dataLoaded = false;
|
||||||
section?: CoreCourseSection & {
|
section?: CoreCourseSection & {
|
||||||
|
@ -158,13 +159,17 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy {
|
||||||
// @todo promises.push(this.prefetchDelegate.invalidateModules(this.section.modules, this.siteHomeId));
|
// @todo promises.push(this.prefetchDelegate.invalidateModules(this.section.modules, this.siteHomeId));
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo promises.push(this.courseBlocksComponent.invalidateBlocks());
|
if (this.courseBlocksComponent) {
|
||||||
|
promises.push(this.courseBlocksComponent.invalidateBlocks());
|
||||||
|
}
|
||||||
|
|
||||||
Promise.all(promises).finally(async () => {
|
Promise.all(promises).finally(async () => {
|
||||||
const p2: Promise<unknown>[] = [];
|
const p2: Promise<unknown>[] = [];
|
||||||
|
|
||||||
p2.push(this.loadContent());
|
p2.push(this.loadContent());
|
||||||
// @todo p2.push(this.courseBlocksComponent.loadContent());
|
if (this.courseBlocksComponent) {
|
||||||
|
p2.push(this.courseBlocksComponent.loadContent());
|
||||||
|
}
|
||||||
|
|
||||||
await Promise.all(p2).finally(() => {
|
await Promise.all(p2).finally(() => {
|
||||||
refresher?.detail.complete();
|
refresher?.detail.complete();
|
||||||
|
|
Loading…
Reference in New Issue