MOBILE-3664 siteplugins: Support home delegate for plugins

main
Dani Palou 2021-03-05 14:48:00 +01:00
parent 98bea1f502
commit 3249647f2a
6 changed files with 128 additions and 18 deletions

View File

@ -23,6 +23,7 @@ import {
AfterViewInit,
ViewChild,
ElementRef,
SimpleChange,
} from '@angular/core';
import { IonSlides } from '@ionic/angular';
import { BackButtonEvent } from '@ionic/core';
@ -153,7 +154,8 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft
/**
* Detect changes on input properties.
*/
ngOnChanges(): void {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
ngOnChanges(changes: Record<string, SimpleChange>): void {
// Wait for ngAfterViewInit so it works in the case that each tab has its own component.
if (!this.initialized && this.hideUntil && this.afterViewInitTriggered) {
// Tabs should be shown, initialize them.

View File

@ -21,6 +21,7 @@ import {
AfterViewInit,
ViewChild,
ElementRef,
SimpleChange,
} from '@angular/core';
import { IonTabs } from '@ionic/angular';
import { Subscription } from 'rxjs';
@ -70,17 +71,6 @@ export class CoreTabsOutletComponent extends CoreTabsBaseComponent<CoreTabsOutle
super(element);
}
/**
* Component being initialized.
*/
async ngOnInit(): Promise<void> {
super.ngOnInit();
this.tabs.forEach((tab) => {
this.initTab(tab);
});
}
/**
* Init tab info.
*
@ -117,12 +107,16 @@ export class CoreTabsOutletComponent extends CoreTabsBaseComponent<CoreTabsOutle
/**
* Detect changes on input properties.
*/
ngOnChanges(): void {
this.tabs.forEach((tab) => {
this.initTab(tab);
});
ngOnChanges(changes: Record<string, SimpleChange>): void {
if (changes.tabs) {
this.tabs.forEach((tab) => {
this.initTab(tab);
});
super.ngOnChanges();
this.calculateSlides();
}
super.ngOnChanges(changes);
}
/**

View File

@ -0,0 +1,58 @@
// (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 { CoreMainMenuHomeHandler, CoreMainMenuHomeHandlerData } from '@features/mainmenu/services/home-delegate';
import {
CoreSitePluginsContent,
CoreSitePluginsMainMenuHomeHandlerData,
CoreSitePluginsPlugin,
} from '@features/siteplugins/services/siteplugins';
import { CoreSitePluginsBaseHandler } from './base-handler';
/**
* Handler to display a site plugin in the main menu.
*/
export class CoreSitePluginsMainMenuHomeHandler extends CoreSitePluginsBaseHandler implements CoreMainMenuHomeHandler {
priority: number;
constructor(
name: string,
protected title: string,
protected plugin: CoreSitePluginsPlugin,
protected handlerSchema: CoreSitePluginsMainMenuHomeHandlerData,
protected initResult: CoreSitePluginsContent | null,
) {
super(name);
this.priority = handlerSchema.priority || 0;
}
/**
* @inheritdoc
*/
getDisplayData(): CoreMainMenuHomeHandlerData {
return {
title: this.title,
class: this.handlerSchema.displaydata?.class,
page: `siteplugins/${this.plugin.component}/${this.handlerSchema.method}/0`,
pageParams: {
title: this.title,
initResult: this.initResult,
ptrEnabled: this.handlerSchema.ptrenabled,
},
};
}
}

View File

@ -74,8 +74,11 @@ import {
CoreSitePluginsBlockHandlerData,
CoreSitePluginsHandlerCommonData,
CoreSitePluginsInitHandlerData,
CoreSitePluginsMainMenuHomeHandlerData,
} from './siteplugins';
import { makeSingleton } from '@singletons';
import { CoreMainMenuHomeDelegate } from '@features/mainmenu/services/home-delegate';
import { CoreSitePluginsMainMenuHomeHandler } from '../classes/handlers/main-menu-home-handler';
const HANDLER_DISABLED = 'core_site_plugins_helper_handler_disabled';
@ -535,6 +538,10 @@ export class CoreSitePluginsHelperProvider {
uniqueName = await this.registerWorkshopAssessmentStrategyHandler(plugin, handlerName, handlerSchema);
break;
case 'CoreMainMenuHomeDelegate':
uniqueName = await this.registerMainMenuHomeHandler(plugin, handlerName, handlerSchema, initResult);
break;
default:
// Nothing to do.
}
@ -1130,6 +1137,41 @@ export class CoreSitePluginsHelperProvider {
CoreEvents.trigger(CoreEvents.SITE_PLUGINS_COURSE_RESTRICT_UPDATED, {});
}
/**
* Given a handler in a plugin, register it in the main menu home delegate.
*
* @param plugin Data of the plugin.
* @param handlerName Name of the handler in the plugin.
* @param handlerSchema Data about the handler.
* @param initResult Result of the init WS call.
* @return A string to identify the handler.
*/
protected registerMainMenuHomeHandler(
plugin: CoreSitePluginsPlugin,
handlerName: string,
handlerSchema: CoreSitePluginsMainMenuHomeHandlerData,
initResult: CoreSitePluginsContent | null,
): string | undefined {
if (!handlerSchema.displaydata) {
// Required data not provided, stop.
this.logger.warn('Ignore site plugin because it doesn\'t provide displaydata', plugin, handlerSchema);
return;
}
this.logger.debug('Register site plugin in main menu home delegate:', plugin, handlerSchema, initResult);
// Create and register the handler.
const uniqueName = CoreSitePlugins.getHandlerUniqueName(plugin, handlerName);
const prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title || 'pluginname');
CoreMainMenuHomeDelegate.registerHandler(
new CoreSitePluginsMainMenuHomeHandler(uniqueName, prefixedTitle, plugin, handlerSchema, initResult),
);
return uniqueName;
}
}
export const CoreSitePluginsHelper = makeSingleton(CoreSitePluginsHelperProvider);

View File

@ -784,7 +784,7 @@ export type CoreSitePluginsPlugin = CoreSitePluginsWSPlugin & {
export type CoreSitePluginsHandlerData = CoreSitePluginsInitHandlerData | CoreSitePluginsCourseOptionHandlerData |
CoreSitePluginsMainMenuHandlerData | CoreSitePluginsCourseModuleHandlerData | CoreSitePluginsCourseFormatHandlerData |
CoreSitePluginsUserHandlerData | CoreSitePluginsSettingsHandlerData | CoreSitePluginsMessageOutputHandlerData |
CoreSitePluginsBlockHandlerData;
CoreSitePluginsBlockHandlerData | CoreSitePluginsMainMenuHomeHandlerData;
/**
* Plugin handler data common to all delegates.
@ -920,3 +920,15 @@ export type CoreSitePluginsInitHandlerData = CoreSitePluginsHandlerCommonData &
methodJSResult?: any; // eslint-disable-line @typescript-eslint/no-explicit-any
methodOtherdata?: Record<string, unknown>;
};
/**
* Main menu home handler specific data.
*/
export type CoreSitePluginsMainMenuHomeHandlerData = CoreSitePluginsHandlerCommonData & {
displaydata?: {
title?: string;
class?: string;
};
priority?: number;
ptrenabled?: boolean;
};

View File

@ -17,6 +17,7 @@ import { Routes } from '@angular/router';
import { CoreCourseIndexRoutingModule } from '@features/course/pages/index/index-routing.module';
import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-routing.module';
import { CoreMainMenuHomeRoutingModule } from '@features/mainmenu/pages/home/home-routing.module';
import { CoreSitePluginsComponentsModule } from './components/components.module';
import { CoreSitePluginsHelper } from './services/siteplugins-helper';
@ -39,6 +40,7 @@ const courseIndexRoutes: Routes = [
imports: [
CoreMainMenuTabRoutingModule.forChild(routes),
CoreCourseIndexRoutingModule.forChild({ children: courseIndexRoutes }),
CoreMainMenuHomeRoutingModule.forChild({ children: routes }),
CoreSitePluginsComponentsModule,
],
providers: [