MOBILE-3942 core: Improve dynamic component calls

main
Noel De Martin 2022-06-22 14:40:56 +02:00
parent 0df9f3651b
commit 86355bce01
57 changed files with 179 additions and 96 deletions

View File

@ -46,7 +46,7 @@ export class AddonBlockActivityModulesComponent extends CoreBlockBaseComponent i
* *
* @return Resolved when done. * @return Resolved when done.
*/ */
protected async invalidateContent(): Promise<void> { async invalidateContent(): Promise<void> {
await CoreCourse.invalidateSections(this.instanceId); await CoreCourse.invalidateSections(this.instanceId);
} }

View File

@ -161,7 +161,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
/** /**
* @inheritdoc * @inheritdoc
*/ */
protected async invalidateContent(): Promise<void> { async invalidateContent(): Promise<void> {
const courseIds = this.allCourses.map((course) => course.id); const courseIds = this.allCourses.map((course) => course.id);
await this.invalidateCourses(courseIds); await this.invalidateCourses(courseIds);

View File

@ -79,7 +79,7 @@ export class AddonBlockRecentlyAccessedCoursesComponent extends CoreBlockBaseCom
/** /**
* @inheritdoc * @inheritdoc
*/ */
protected async invalidateContent(): Promise<void> { async invalidateContent(): Promise<void> {
const courseIds = this.courses.map((course) => course.id); const courseIds = this.courses.map((course) => course.id);
await this.invalidateCourses(courseIds); await this.invalidateCourses(courseIds);

View File

@ -60,7 +60,7 @@ export class AddonBlockRecentlyAccessedItemsComponent extends CoreBlockBaseCompo
* *
* @return Resolved when done. * @return Resolved when done.
*/ */
protected async invalidateContent(): Promise<void> { async invalidateContent(): Promise<void> {
await AddonBlockRecentlyAccessedItems.invalidateRecentItems(); await AddonBlockRecentlyAccessedItems.invalidateRecentItems();
} }

View File

@ -53,7 +53,7 @@ export class AddonBlockSiteMainMenuComponent extends CoreBlockBaseComponent impl
* *
* @return Resolved when done. * @return Resolved when done.
*/ */
protected async invalidateContent(): Promise<void> { async invalidateContent(): Promise<void> {
const promises: Promise<void>[] = []; const promises: Promise<void>[] = [];
promises.push(CoreCourse.invalidateSections(this.siteHomeId)); promises.push(CoreCourse.invalidateSections(this.siteHomeId));

View File

@ -75,7 +75,7 @@ export class AddonBlockStarredCoursesComponent extends CoreBlockBaseComponent im
/** /**
* @inheritdoc * @inheritdoc
*/ */
protected async invalidateContent(): Promise<void> { async invalidateContent(): Promise<void> {
const courseIds = this.courses.map((course) => course.id); const courseIds = this.courses.map((course) => course.id);
await this.invalidateCourses(courseIds); await this.invalidateCourses(courseIds);

View File

@ -101,7 +101,7 @@ export class AddonBlockTimelineComponent extends CoreBlockBaseComponent implemen
* *
* @return Resolved when done. * @return Resolved when done.
*/ */
protected invalidateContent(): Promise<void> { invalidateContent(): Promise<void> {
const promises: Promise<void>[] = []; const promises: Promise<void>[] = [];
promises.push(AddonBlockTimeline.invalidateActionEventsByTimesort()); promises.push(AddonBlockTimeline.invalidateActionEventsByTimesort());

View File

@ -26,7 +26,7 @@ import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission }
@Component({ @Component({
template: '', template: '',
}) })
export class AddonModAssignFeedbackPluginBaseComponent { export class AddonModAssignFeedbackPluginBaseComponent implements IAddonModAssignFeedbackPluginComponent {
@Input() assign!: AddonModAssignAssign; // The assignment. @Input() assign!: AddonModAssignAssign; // The assignment.
@Input() submission!: AddonModAssignSubmission; // The submission. @Input() submission!: AddonModAssignSubmission; // The submission.
@ -65,12 +65,24 @@ export class AddonModAssignFeedbackPluginBaseComponent {
} }
/** /**
* Invalidate the data. * @inheritdoc
*
* @return Promise resolved when done.
*/ */
async invalidate(): Promise<void> { async invalidate(): Promise<void> {
return; return;
} }
} }
/**
* Interface for component to render a feedback plugin.
*/
export interface IAddonModAssignFeedbackPluginComponent {
/**
* Invalidate the data.
*
* @return Promise resolved when done.
*/
invalidate(): Promise<void>;
}

View File

@ -12,6 +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 type { IAddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
import { Component, Input, OnInit, ViewChild, Type } from '@angular/core'; import { Component, Input, OnInit, ViewChild, Type } from '@angular/core';
import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component'; import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component';
import { CoreWSFile } from '@services/ws'; import { CoreWSFile } from '@services/ws';
@ -34,7 +35,7 @@ import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate
}) })
export class AddonModAssignFeedbackPluginComponent implements OnInit { export class AddonModAssignFeedbackPluginComponent implements OnInit {
@ViewChild(CoreDynamicComponent) dynamicComponent!: CoreDynamicComponent; @ViewChild(CoreDynamicComponent) dynamicComponent!: CoreDynamicComponent<IAddonModAssignFeedbackPluginComponent>;
@Input() assign!: AddonModAssignAssign; // The assignment. @Input() assign!: AddonModAssignAssign; // The assignment.
@Input() submission!: AddonModAssignSubmission; // The submission. @Input() submission!: AddonModAssignSubmission; // The submission.
@ -43,7 +44,7 @@ export class AddonModAssignFeedbackPluginComponent implements OnInit {
@Input() canEdit = false; // Whether the user can edit. @Input() canEdit = false; // Whether the user can edit.
@Input() edit = false; // Whether the user is editing. @Input() edit = false; // Whether the user is editing.
pluginComponent?: Type<unknown>; // Component to render the plugin. pluginComponent?: Type<IAddonModAssignFeedbackPluginComponent>; // Component to render the plugin.
data?: AddonModAssignFeedbackPluginData; // Data to pass to the component. data?: AddonModAssignFeedbackPluginData; // Data to pass to the component.
// Data to render the plugin if it isn't supported. // Data to render the plugin if it isn't supported.
@ -101,7 +102,7 @@ export class AddonModAssignFeedbackPluginComponent implements OnInit {
* @return Promise resolved when done. * @return Promise resolved when done.
*/ */
async invalidate(): Promise<void> { async invalidate(): Promise<void> {
await this.dynamicComponent.callComponentFunction('invalidate', []); await this.dynamicComponent.callComponentMethod('invalidate');
} }
} }

View File

@ -24,6 +24,7 @@ import {
import { AddonModAssignHelper, AddonModAssignPluginConfig } from '../../services/assign-helper'; import { AddonModAssignHelper, AddonModAssignPluginConfig } from '../../services/assign-helper';
import { AddonModAssignSubmissionDelegate } from '../../services/submission-delegate'; import { AddonModAssignSubmissionDelegate } from '../../services/submission-delegate';
import { CoreFileEntry } from '@services/file-helper'; import { CoreFileEntry } from '@services/file-helper';
import type { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
/** /**
* Component that displays an assignment submission plugin. * Component that displays an assignment submission plugin.
@ -34,7 +35,7 @@ import { CoreFileEntry } from '@services/file-helper';
}) })
export class AddonModAssignSubmissionPluginComponent implements OnInit { export class AddonModAssignSubmissionPluginComponent implements OnInit {
@ViewChild(CoreDynamicComponent) dynamicComponent!: CoreDynamicComponent; @ViewChild(CoreDynamicComponent) dynamicComponent!: CoreDynamicComponent<AddonModAssignSubmissionPluginBaseComponent>;
@Input() assign!: AddonModAssignAssign; // The assignment. @Input() assign!: AddonModAssignAssign; // The assignment.
@Input() submission!: AddonModAssignSubmission; // The submission. @Input() submission!: AddonModAssignSubmission; // The submission.
@ -42,7 +43,7 @@ export class AddonModAssignSubmissionPluginComponent implements OnInit {
@Input() edit = false; // Whether the user is editing. @Input() edit = false; // Whether the user is editing.
@Input() allowOffline = false; // Whether to allow offline. @Input() allowOffline = false; // Whether to allow offline.
pluginComponent?: Type<unknown>; // Component to render the plugin. pluginComponent?: Type<AddonModAssignSubmissionPluginBaseComponent>; // Component to render the plugin.
data?: AddonModAssignSubmissionPluginData; // Data to pass to the component. data?: AddonModAssignSubmissionPluginData; // Data to pass to the component.
// Data to render the plugin if it isn't supported. // Data to render the plugin if it isn't supported.
@ -99,7 +100,7 @@ export class AddonModAssignSubmissionPluginComponent implements OnInit {
* @return Promise resolved when done. * @return Promise resolved when done.
*/ */
async invalidate(): Promise<void> { async invalidate(): Promise<void> {
await this.dynamicComponent.callComponentFunction('invalidate', []); await this.dynamicComponent.callComponentMethod('invalidate');
} }
} }

View File

@ -12,6 +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 type { IAddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
import { import {
AddonModAssignPlugin, AddonModAssignPlugin,
AddonModAssignAssign, AddonModAssignAssign,
@ -80,7 +81,7 @@ export class AddonModAssignFeedbackCommentsHandlerService implements AddonModAss
* *
* @return The component (or promise resolved with component) to use, undefined if not found. * @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
getComponent(): Type<unknown> { getComponent(): Type<IAddonModAssignFeedbackPluginComponent> {
return AddonModAssignFeedbackCommentsComponent; return AddonModAssignFeedbackCommentsComponent;
} }

View File

@ -23,6 +23,7 @@ import { Injectable, Type } from '@angular/core';
import { CoreWSFile } from '@services/ws'; import { CoreWSFile } from '@services/ws';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModAssignFeedbackEditPdfComponent } from '../component/editpdf'; import { AddonModAssignFeedbackEditPdfComponent } from '../component/editpdf';
import type { IAddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
/** /**
* Handler for edit pdf feedback plugin. * Handler for edit pdf feedback plugin.
@ -39,7 +40,7 @@ export class AddonModAssignFeedbackEditPdfHandlerService implements AddonModAssi
* *
* @return The component (or promise resolved with component) to use, undefined if not found. * @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
getComponent(): Type<unknown> { getComponent(): Type<IAddonModAssignFeedbackPluginComponent> {
return AddonModAssignFeedbackEditPdfComponent; return AddonModAssignFeedbackEditPdfComponent;
} }

View File

@ -12,6 +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 type { IAddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
import { import {
AddonModAssignPlugin, AddonModAssignPlugin,
AddonModAssignAssign, AddonModAssignAssign,
@ -39,7 +40,7 @@ export class AddonModAssignFeedbackFileHandlerService implements AddonModAssignF
* *
* @return The component (or promise resolved with component) to use, undefined if not found. * @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
getComponent(): Type<unknown> { getComponent(): Type<IAddonModAssignFeedbackPluginComponent> {
return AddonModAssignFeedbackFileComponent; return AddonModAssignFeedbackFileComponent;
} }

View File

@ -20,6 +20,7 @@ import { makeSingleton } from '@singletons';
import { CoreWSFile } from '@services/ws'; import { CoreWSFile } from '@services/ws';
import { AddonModAssignSubmissionFormatted } from './assign-helper'; import { AddonModAssignSubmissionFormatted } from './assign-helper';
import { CoreFormFields } from '@singletons/form'; import { CoreFormFields } from '@singletons/form';
import type { IAddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
/** /**
* Interface that all feedback handlers must implement. * Interface that all feedback handlers must implement.
@ -48,7 +49,9 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler {
* @param plugin The plugin object. * @param plugin The plugin object.
* @return The component (or promise resolved with component) to use, undefined if not found. * @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
getComponent?(plugin: AddonModAssignPlugin): Type<unknown> | undefined | Promise<Type<unknown> | undefined>; getComponent?(plugin: AddonModAssignPlugin): Type<IAddonModAssignFeedbackPluginComponent>
| undefined
| Promise<Type<IAddonModAssignFeedbackPluginComponent> | undefined>;
/** /**
* Return the draft saved data of the feedback plugin. * Return the draft saved data of the feedback plugin.
@ -209,7 +212,9 @@ export class AddonModAssignFeedbackDelegateService extends CoreDelegate<AddonMod
* @param plugin The plugin object. * @param plugin The plugin object.
* @return Promise resolved with the component to use, undefined if not found. * @return Promise resolved with the component to use, undefined if not found.
*/ */
async getComponentForPlugin(plugin: AddonModAssignPlugin): Promise<Type<unknown> | undefined> { async getComponentForPlugin(
plugin: AddonModAssignPlugin,
): Promise<Type<IAddonModAssignFeedbackPluginComponent> | undefined> {
return await this.executeFunctionOnEnabled(plugin.type, 'getComponent', [plugin]); return await this.executeFunctionOnEnabled(plugin.type, 'getComponent', [plugin]);
} }

View File

@ -20,6 +20,7 @@ import { makeSingleton } from '@singletons';
import { CoreWSFile } from '@services/ws'; import { CoreWSFile } from '@services/ws';
import { AddonModAssignSubmissionsDBRecordFormatted } from './assign-offline'; import { AddonModAssignSubmissionsDBRecordFormatted } from './assign-offline';
import { CoreFormFields } from '@singletons/form'; import { CoreFormFields } from '@singletons/form';
import type { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
/** /**
* Interface that all submission handlers must implement. * Interface that all submission handlers must implement.
@ -122,7 +123,9 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler {
getComponent?( getComponent?(
plugin: AddonModAssignPlugin, plugin: AddonModAssignPlugin,
edit?: boolean, edit?: boolean,
): Type<unknown> | undefined | Promise<Type<unknown> | undefined>; ): Type<AddonModAssignSubmissionPluginBaseComponent>
| undefined
| Promise<Type<AddonModAssignSubmissionPluginBaseComponent> | undefined>;
/** /**
* Get files used by this plugin. * Get files used by this plugin.
@ -365,7 +368,10 @@ export class AddonModAssignSubmissionDelegateService extends CoreDelegate<AddonM
* @param edit Whether the user is editing. * @param edit Whether the user is editing.
* @return Promise resolved with the component to use, undefined if not found. * @return Promise resolved with the component to use, undefined if not found.
*/ */
async getComponentForPlugin(plugin: AddonModAssignPlugin, edit?: boolean): Promise<Type<unknown> | undefined> { async getComponentForPlugin(
plugin: AddonModAssignPlugin,
edit?: boolean,
): Promise<Type<AddonModAssignSubmissionPluginBaseComponent> | undefined> {
return await this.executeFunctionOnEnabled(plugin.type, 'getComponent', [plugin, edit]); return await this.executeFunctionOnEnabled(plugin.type, 'getComponent', [plugin, edit]);
} }

View File

@ -12,6 +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 type { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
import { AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin } from '@addons/mod/assign/services/assign'; import { AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin } from '@addons/mod/assign/services/assign';
import { AddonModAssignSubmissionHandler } from '@addons/mod/assign/services/submission-delegate'; import { AddonModAssignSubmissionHandler } from '@addons/mod/assign/services/submission-delegate';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
@ -48,7 +49,7 @@ export class AddonModAssignSubmissionCommentsHandlerService implements AddonModA
* @param edit Whether the user is editing. * @param edit Whether the user is editing.
* @return The component (or promise resolved with component) to use, undefined if not found. * @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
getComponent(plugin: AddonModAssignPlugin, edit = false): Type<unknown> | undefined { getComponent(plugin: AddonModAssignPlugin, edit = false): Type<AddonModAssignSubmissionPluginBaseComponent> | undefined {
return edit ? undefined : AddonModAssignSubmissionCommentsComponent; return edit ? undefined : AddonModAssignSubmissionCommentsComponent;
} }

View File

@ -31,6 +31,7 @@ import { CoreWSFile } from '@services/ws';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModAssignSubmissionFileComponent } from '../component/file'; import { AddonModAssignSubmissionFileComponent } from '../component/file';
import { FileEntry } from '@ionic-native/file/ngx'; import { FileEntry } from '@ionic-native/file/ngx';
import type { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
/** /**
* Handler for file submission plugin. * Handler for file submission plugin.
@ -110,7 +111,7 @@ export class AddonModAssignSubmissionFileHandlerService implements AddonModAssig
* *
* @return The component (or promise resolved with component) to use, undefined if not found. * @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
getComponent(): Type<unknown> { getComponent(): Type<AddonModAssignSubmissionPluginBaseComponent> {
return AddonModAssignSubmissionFileComponent; return AddonModAssignSubmissionFileComponent;
} }

View File

@ -12,6 +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 type { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
import { import {
AddonModAssignAssign, AddonModAssignAssign,
AddonModAssignSubmission, AddonModAssignSubmission,
@ -106,7 +107,7 @@ export class AddonModAssignSubmissionOnlineTextHandlerService implements AddonMo
* *
* @return The component (or promise resolved with component) to use, undefined if not found. * @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
getComponent(): Type<unknown> { getComponent(): Type<AddonModAssignSubmissionPluginBaseComponent> {
return AddonModAssignSubmissionOnlineTextComponent; return AddonModAssignSubmissionOnlineTextComponent;
} }

View File

@ -23,7 +23,7 @@ import { AddonModDataData, AddonModDataEntryField, AddonModDataField, AddonModDa
@Component({ @Component({
template: '', template: '',
}) })
export abstract class AddonModDataFieldPluginComponent implements OnInit, OnChanges { export abstract class AddonModDataFieldPluginBaseComponent implements OnInit, OnChanges {
@Input() mode!: AddonModDataTemplateMode; // The render mode. @Input() mode!: AddonModDataTemplateMode; // The render mode.
@Input() field!: AddonModDataField; // The field to render. @Input() field!: AddonModDataField; // The field to render.

View File

@ -16,7 +16,7 @@ import { Component, OnInit, OnChanges, ViewChild, Input, Output, SimpleChange, T
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component'; import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component';
import { CoreFormFields } from '@singletons/form'; import { CoreFormFields } from '@singletons/form';
import { AddonModDataEntryFieldInitialized } from '../../classes/field-plugin-component'; import { AddonModDataEntryFieldInitialized, AddonModDataFieldPluginBaseComponent } from '../../classes/base-field-plugin-component';
import { AddonModDataData, AddonModDataField, AddonModDataTemplateMode } from '../../services/data'; import { AddonModDataData, AddonModDataField, AddonModDataTemplateMode } from '../../services/data';
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate'; import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
@ -29,7 +29,7 @@ import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate'
}) })
export class AddonModDataFieldPluginComponent implements OnInit, OnChanges { export class AddonModDataFieldPluginComponent implements OnInit, OnChanges {
@ViewChild(CoreDynamicComponent) dynamicComponent?: CoreDynamicComponent; @ViewChild(CoreDynamicComponent) dynamicComponent?: CoreDynamicComponent<AddonModDataFieldPluginBaseComponent>;
@Input() mode!: AddonModDataTemplateMode; // The render mode. @Input() mode!: AddonModDataTemplateMode; // The render mode.
@Input() field!: AddonModDataField; // The field to render. @Input() field!: AddonModDataField; // The field to render.
@ -42,7 +42,7 @@ export class AddonModDataFieldPluginComponent implements OnInit, OnChanges {
// Output called when the field is initialized with a value and it didn't have one already. // Output called when the field is initialized with a value and it didn't have one already.
@Output() onFieldInit = new EventEmitter<AddonModDataEntryFieldInitialized>(); @Output() onFieldInit = new EventEmitter<AddonModDataEntryFieldInitialized>();
fieldComponent?: Type<unknown>; // Component to render the plugin. fieldComponent?: Type<AddonModDataFieldPluginBaseComponent>; // Component to render the plugin.
pluginData?: AddonDataFieldPluginComponentData; // Data to pass to the component. pluginData?: AddonDataFieldPluginComponentData; // Data to pass to the component.
fieldLoaded = false; fieldLoaded = false;

View File

@ -14,7 +14,7 @@
import { AddonModDataEntryField } from '@addons/mod/data/services/data'; import { AddonModDataEntryField } from '@addons/mod/data/services/data';
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component'; import { AddonModDataFieldPluginBaseComponent } from '../../../classes/base-field-plugin-component';
/** /**
* Component to render data checkbox field. * Component to render data checkbox field.
@ -23,7 +23,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-checkbox', selector: 'addon-mod-data-field-checkbox',
templateUrl: 'addon-mod-data-field-checkbox.html', templateUrl: 'addon-mod-data-field-checkbox.html',
}) })
export class AddonModDataFieldCheckboxComponent extends AddonModDataFieldPluginComponent { export class AddonModDataFieldCheckboxComponent extends AddonModDataFieldPluginBaseComponent {
options: { options: {
key: string; key: string;

View File

@ -22,6 +22,7 @@ import { Injectable, Type } from '@angular/core';
import { CoreFormFields } from '@singletons/form'; import { CoreFormFields } from '@singletons/form';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { AddonModDataFieldCheckboxComponent } from '../component/checkbox'; import { AddonModDataFieldCheckboxComponent } from '../component/checkbox';
import type { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
/** /**
* Handler for checkbox data field plugin. * Handler for checkbox data field plugin.
@ -35,7 +36,7 @@ export class AddonModDataFieldCheckboxHandlerService implements AddonModDataFiel
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown> { getComponent(): Type<AddonModDataFieldPluginBaseComponent> {
return AddonModDataFieldCheckboxComponent; return AddonModDataFieldCheckboxComponent;
} }

View File

@ -15,7 +15,7 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component'; import { AddonModDataFieldPluginBaseComponent } from '../../../classes/base-field-plugin-component';
/** /**
* Component to render data date field. * Component to render data date field.
@ -24,7 +24,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-date', selector: 'addon-mod-data-field-date',
templateUrl: 'addon-mod-data-field-date.html', templateUrl: 'addon-mod-data-field-date.html',
}) })
export class AddonModDataFieldDateComponent extends AddonModDataFieldPluginComponent { export class AddonModDataFieldDateComponent extends AddonModDataFieldPluginBaseComponent {
format!: string; format!: string;
displayDate?: number; displayDate?: number;

View File

@ -24,6 +24,7 @@ import { CoreFormFields } from '@singletons/form';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { AddonModDataFieldDateComponent } from '../component/date'; import { AddonModDataFieldDateComponent } from '../component/date';
import type { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
/** /**
* Handler for date data field plugin. * Handler for date data field plugin.
@ -37,7 +38,7 @@ export class AddonModDataFieldDateHandlerService implements AddonModDataFieldHan
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown>{ getComponent(): Type<AddonModDataFieldPluginBaseComponent> {
return AddonModDataFieldDateComponent; return AddonModDataFieldDateComponent;
} }

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { AddonModDataEntryField, AddonModDataProvider } from '@addons/mod/data/services/data'; import { AddonModDataEntryField, AddonModDataProvider } from '@addons/mod/data/services/data';
import { AddonModDataFieldPluginComponent } from '@addons/mod/data/classes/field-plugin-component'; import { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
import { CoreFileSession } from '@services/file-session'; import { CoreFileSession } from '@services/file-session';
import { CoreFileEntry } from '@services/file-helper'; import { CoreFileEntry } from '@services/file-helper';
@ -24,7 +24,7 @@ import { CoreFileEntry } from '@services/file-helper';
selector: 'addon-mod-data-field-file', selector: 'addon-mod-data-field-file',
templateUrl: 'addon-mod-data-field-file.html', templateUrl: 'addon-mod-data-field-file.html',
}) })
export class AddonModDataFieldFileComponent extends AddonModDataFieldPluginComponent { export class AddonModDataFieldFileComponent extends AddonModDataFieldPluginBaseComponent {
files: CoreFileEntry[] = []; files: CoreFileEntry[] = [];
component?: string; component?: string;

View File

@ -28,6 +28,7 @@ import { CoreFormFields } from '@singletons/form';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { AddonModDataFieldFileComponent } from '../component/file'; import { AddonModDataFieldFileComponent } from '../component/file';
import { CoreFileEntry } from '@services/file-helper'; import { CoreFileEntry } from '@services/file-helper';
import type { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
/** /**
* Handler for file data field plugin. * Handler for file data field plugin.
@ -41,7 +42,7 @@ export class AddonModDataFieldFileHandlerService implements AddonModDataFieldHan
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown>{ getComponent(): Type<AddonModDataFieldPluginBaseComponent> {
return AddonModDataFieldFileComponent; return AddonModDataFieldFileComponent;
} }

View File

@ -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 { AddonModDataFieldPluginComponent } from '@addons/mod/data/classes/field-plugin-component'; import { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
import { AddonModDataEntryField } from '@addons/mod/data/services/data'; import { AddonModDataEntryField } from '@addons/mod/data/services/data';
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { FormBuilder } from '@angular/forms'; import { FormBuilder } from '@angular/forms';
@ -30,7 +30,7 @@ import { DomSanitizer } from '@singletons';
selector: 'addon-mod-data-field-latlong', selector: 'addon-mod-data-field-latlong',
templateUrl: 'addon-mod-data-field-latlong.html', templateUrl: 'addon-mod-data-field-latlong.html',
}) })
export class AddonModDataFieldLatlongComponent extends AddonModDataFieldPluginComponent { export class AddonModDataFieldLatlongComponent extends AddonModDataFieldPluginBaseComponent {
north?: number; north?: number;
east?: number; east?: number;

View File

@ -23,6 +23,7 @@ import { Injectable, Type } from '@angular/core';
import { CoreFormFields } from '@singletons/form'; import { CoreFormFields } from '@singletons/form';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { AddonModDataFieldLatlongComponent } from '../component/latlong'; import { AddonModDataFieldLatlongComponent } from '../component/latlong';
import type { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
/** /**
* Handler for latlong data field plugin. * Handler for latlong data field plugin.
@ -36,7 +37,7 @@ export class AddonModDataFieldLatlongHandlerService implements AddonModDataField
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown>{ getComponent(): Type<AddonModDataFieldPluginBaseComponent> {
return AddonModDataFieldLatlongComponent; return AddonModDataFieldLatlongComponent;
} }

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component'; import { AddonModDataFieldPluginBaseComponent } from '../../../classes/base-field-plugin-component';
/** /**
* Component to render data menu field. * Component to render data menu field.
@ -22,7 +22,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-menu', selector: 'addon-mod-data-field-menu',
templateUrl: 'addon-mod-data-field-menu.html', templateUrl: 'addon-mod-data-field-menu.html',
}) })
export class AddonModDataFieldMenuComponent extends AddonModDataFieldPluginComponent { export class AddonModDataFieldMenuComponent extends AddonModDataFieldPluginBaseComponent {
options: string[] = []; options: string[] = [];

View File

@ -23,6 +23,7 @@ import { Injectable, Type } from '@angular/core';
import { CoreFormFields } from '@singletons/form'; import { CoreFormFields } from '@singletons/form';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { AddonModDataFieldMenuComponent } from '../component/menu'; import { AddonModDataFieldMenuComponent } from '../component/menu';
import type { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
/** /**
* Handler for menu data field plugin. * Handler for menu data field plugin.
@ -36,7 +37,7 @@ export class AddonModDataFieldMenuHandlerService implements AddonModDataFieldHan
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown>{ getComponent(): Type<AddonModDataFieldPluginBaseComponent> {
return AddonModDataFieldMenuComponent; return AddonModDataFieldMenuComponent;
} }

View File

@ -14,7 +14,7 @@
import { AddonModDataEntryField } from '@addons/mod/data/services/data'; import { AddonModDataEntryField } from '@addons/mod/data/services/data';
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component'; import { AddonModDataFieldPluginBaseComponent } from '../../../classes/base-field-plugin-component';
/** /**
* Component to render data multimenu field. * Component to render data multimenu field.
@ -23,7 +23,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-multimenu', selector: 'addon-mod-data-field-multimenu',
templateUrl: 'addon-mod-data-field-multimenu.html', templateUrl: 'addon-mod-data-field-multimenu.html',
}) })
export class AddonModDataFieldMultimenuComponent extends AddonModDataFieldPluginComponent { export class AddonModDataFieldMultimenuComponent extends AddonModDataFieldPluginBaseComponent {
options: { options: {
key: string; key: string;

View File

@ -23,6 +23,7 @@ import { Injectable, Type } from '@angular/core';
import { CoreFormFields } from '@singletons/form'; import { CoreFormFields } from '@singletons/form';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { AddonModDataFieldMultimenuComponent } from '../component/multimenu'; import { AddonModDataFieldMultimenuComponent } from '../component/multimenu';
import type { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
/** /**
* Handler for multimenu data field plugin. * Handler for multimenu data field plugin.
@ -36,7 +37,7 @@ export class AddonModDataFieldMultimenuHandlerService implements AddonModDataFie
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown>{ getComponent(): Type<AddonModDataFieldPluginBaseComponent> {
return AddonModDataFieldMultimenuComponent; return AddonModDataFieldMultimenuComponent;
} }

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component'; import { AddonModDataFieldPluginBaseComponent } from '../../../classes/base-field-plugin-component';
/** /**
* Component to render data number field. * Component to render data number field.
@ -22,7 +22,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-number', selector: 'addon-mod-data-field-number',
templateUrl: 'addon-mod-data-field-number.html', templateUrl: 'addon-mod-data-field-number.html',
}) })
export class AddonModDataFieldNumberComponent extends AddonModDataFieldPluginComponent{ export class AddonModDataFieldNumberComponent extends AddonModDataFieldPluginBaseComponent{
/** /**
* @inheritdoc * @inheritdoc

View File

@ -18,6 +18,7 @@ import { CoreFormFields } from '@singletons/form';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { AddonModDataFieldTextHandlerService } from '../../text/services/handler'; import { AddonModDataFieldTextHandlerService } from '../../text/services/handler';
import { AddonModDataFieldNumberComponent } from '../component/number'; import { AddonModDataFieldNumberComponent } from '../component/number';
import type { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
/** /**
* Handler for number data field plugin. * Handler for number data field plugin.
@ -31,7 +32,7 @@ export class AddonModDataFieldNumberHandlerService extends AddonModDataFieldText
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown>{ getComponent(): Type<AddonModDataFieldPluginBaseComponent> {
return AddonModDataFieldNumberComponent; return AddonModDataFieldNumberComponent;
} }

View File

@ -16,7 +16,7 @@ import { Component } from '@angular/core';
import { CoreFileEntry, CoreFileHelper } from '@services/file-helper'; import { CoreFileEntry, CoreFileHelper } from '@services/file-helper';
import { CoreFileSession } from '@services/file-session'; import { CoreFileSession } from '@services/file-session';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component'; import { AddonModDataFieldPluginBaseComponent } from '../../../classes/base-field-plugin-component';
/** /**
* Component to render data picture field. * Component to render data picture field.
@ -25,7 +25,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-picture', selector: 'addon-mod-data-field-picture',
templateUrl: 'addon-mod-data-field-picture.html', templateUrl: 'addon-mod-data-field-picture.html',
}) })
export class AddonModDataFieldPictureComponent extends AddonModDataFieldPluginComponent { export class AddonModDataFieldPictureComponent extends AddonModDataFieldPluginBaseComponent {
files: CoreFileEntry[] = []; files: CoreFileEntry[] = [];
component?: string; component?: string;

View File

@ -28,6 +28,7 @@ import { CoreFormFields } from '@singletons/form';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { AddonModDataFieldPictureComponent } from '../component/picture'; import { AddonModDataFieldPictureComponent } from '../component/picture';
import { CoreFileEntry } from '@services/file-helper'; import { CoreFileEntry } from '@services/file-helper';
import type { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
/** /**
* Handler for picture data field plugin. * Handler for picture data field plugin.
@ -41,7 +42,7 @@ export class AddonModDataFieldPictureHandlerService implements AddonModDataField
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown>{ getComponent(): Type<AddonModDataFieldPluginBaseComponent> {
return AddonModDataFieldPictureComponent; return AddonModDataFieldPictureComponent;
} }

View File

@ -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 } from '@angular/core'; import { Component } from '@angular/core';
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component'; import { AddonModDataFieldPluginBaseComponent } from '../../../classes/base-field-plugin-component';
/** /**
* Component to render data radiobutton field. * Component to render data radiobutton field.
@ -21,7 +21,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-radiobutton', selector: 'addon-mod-data-field-radiobutton',
templateUrl: 'addon-mod-data-field-radiobutton.html', templateUrl: 'addon-mod-data-field-radiobutton.html',
}) })
export class AddonModDataFieldRadiobuttonComponent extends AddonModDataFieldPluginComponent { export class AddonModDataFieldRadiobuttonComponent extends AddonModDataFieldPluginBaseComponent {
options: string[] = []; options: string[] = [];

View File

@ -23,6 +23,7 @@ import { Injectable, Type } from '@angular/core';
import { CoreFormFields } from '@singletons/form'; import { CoreFormFields } from '@singletons/form';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { AddonModDataFieldRadiobuttonComponent } from '../component/radiobutton'; import { AddonModDataFieldRadiobuttonComponent } from '../component/radiobutton';
import type { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
/** /**
* Handler for checkbox data field plugin. * Handler for checkbox data field plugin.
@ -36,7 +37,7 @@ export class AddonModDataFieldRadiobuttonHandlerService implements AddonModDataF
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown>{ getComponent(): Type<AddonModDataFieldPluginBaseComponent> {
return AddonModDataFieldRadiobuttonComponent; return AddonModDataFieldRadiobuttonComponent;
} }

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component'; import { AddonModDataFieldPluginBaseComponent } from '../../../classes/base-field-plugin-component';
/** /**
* Component to render data text field. * Component to render data text field.
@ -22,7 +22,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-text', selector: 'addon-mod-data-field-text',
templateUrl: 'addon-mod-data-field-text.html', templateUrl: 'addon-mod-data-field-text.html',
}) })
export class AddonModDataFieldTextComponent extends AddonModDataFieldPluginComponent { export class AddonModDataFieldTextComponent extends AddonModDataFieldPluginBaseComponent {
/** /**
* @inheritdoc * @inheritdoc

View File

@ -23,6 +23,7 @@ import { Injectable, Type } from '@angular/core';
import { CoreFormFields } from '@singletons/form'; import { CoreFormFields } from '@singletons/form';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { AddonModDataFieldTextComponent } from '../component/text'; import { AddonModDataFieldTextComponent } from '../component/text';
import type { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
/** /**
* Handler for number data field plugin. * Handler for number data field plugin.
@ -36,7 +37,7 @@ export class AddonModDataFieldTextHandlerService implements AddonModDataFieldHan
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown>{ getComponent(): Type<AddonModDataFieldPluginBaseComponent> {
return AddonModDataFieldTextComponent; return AddonModDataFieldTextComponent;
} }

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component'; import { AddonModDataFieldPluginBaseComponent } from '../../../classes/base-field-plugin-component';
import { AddonModDataEntryField, AddonModDataProvider } from '@addons/mod/data/services/data'; import { AddonModDataEntryField, AddonModDataProvider } from '@addons/mod/data/services/data';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreWSFile } from '@services/ws'; import { CoreWSFile } from '@services/ws';
@ -25,7 +25,7 @@ import { CoreWSFile } from '@services/ws';
selector: 'addon-mod-data-field-textarea', selector: 'addon-mod-data-field-textarea',
templateUrl: 'addon-mod-data-field-textarea.html', templateUrl: 'addon-mod-data-field-textarea.html',
}) })
export class AddonModDataFieldTextareaComponent extends AddonModDataFieldPluginComponent { export class AddonModDataFieldTextareaComponent extends AddonModDataFieldPluginBaseComponent {
component?: string; component?: string;
componentId?: number; componentId?: number;

View File

@ -21,6 +21,7 @@ import { makeSingleton, Translate } from '@singletons';
import { AddonModDataFieldTextHandlerService } from '../../text/services/handler'; import { AddonModDataFieldTextHandlerService } from '../../text/services/handler';
import { AddonModDataFieldTextareaComponent } from '../component/textarea'; import { AddonModDataFieldTextareaComponent } from '../component/textarea';
import { CoreFileEntry } from '@services/file-helper'; import { CoreFileEntry } from '@services/file-helper';
import type { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
/** /**
* Handler for textarea data field plugin. * Handler for textarea data field plugin.
@ -34,7 +35,7 @@ export class AddonModDataFieldTextareaHandlerService extends AddonModDataFieldTe
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown>{ getComponent(): Type<AddonModDataFieldPluginBaseComponent> {
return AddonModDataFieldTextareaComponent; return AddonModDataFieldTextareaComponent;
} }

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
import { AddonModDataEntryField } from '@addons/mod/data/services/data'; import { AddonModDataEntryField } from '@addons/mod/data/services/data';
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component'; import { AddonModDataFieldPluginBaseComponent } from '../../../classes/base-field-plugin-component';
/** /**
* Component to render data url field. * Component to render data url field.
@ -22,7 +22,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-url', selector: 'addon-mod-data-field-url',
templateUrl: 'addon-mod-data-field-url.html', templateUrl: 'addon-mod-data-field-url.html',
}) })
export class AddonModDataFieldUrlComponent extends AddonModDataFieldPluginComponent { export class AddonModDataFieldUrlComponent extends AddonModDataFieldPluginBaseComponent {
autoLink = false; autoLink = false;
displayValue = ''; displayValue = '';

View File

@ -18,6 +18,7 @@ import { CoreFormFields } from '@singletons/form';
import { Translate, makeSingleton } from '@singletons'; import { Translate, makeSingleton } from '@singletons';
import { AddonModDataFieldTextHandlerService } from '../../text/services/handler'; import { AddonModDataFieldTextHandlerService } from '../../text/services/handler';
import { AddonModDataFieldUrlComponent } from '../component/url'; import { AddonModDataFieldUrlComponent } from '../component/url';
import type { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
/** /**
* Handler for url data field plugin. * Handler for url data field plugin.
@ -31,7 +32,7 @@ export class AddonModDataFieldUrlHandlerService extends AddonModDataFieldTextHan
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown>{ getComponent(): Type<AddonModDataFieldPluginBaseComponent> {
return AddonModDataFieldUrlComponent; return AddonModDataFieldUrlComponent;
} }

View File

@ -41,7 +41,7 @@ import {
} from '../../services/data'; } from '../../services/data';
import { AddonModDataHelper } from '../../services/data-helper'; import { AddonModDataHelper } from '../../services/data-helper';
import { CoreDom } from '@singletons/dom'; import { CoreDom } from '@singletons/dom';
import { AddonModDataEntryFieldInitialized } from '../../classes/field-plugin-component'; import { AddonModDataEntryFieldInitialized } from '../../classes/base-field-plugin-component';
/** /**
* Page that displays the view edit page. * Page that displays the view edit page.

View File

@ -24,6 +24,7 @@ import { AddonModDataEntryField,
import { CoreFormFields } from '@singletons/form'; import { CoreFormFields } from '@singletons/form';
import { FileEntry } from '@ionic-native/file/ngx'; import { FileEntry } from '@ionic-native/file/ngx';
import { CoreFileEntry } from '@services/file-helper'; import { CoreFileEntry } from '@services/file-helper';
import type { AddonModDataFieldPluginBaseComponent } from '@addons/mod/data/classes/base-field-plugin-component';
/** /**
* Interface that all fields handlers must implement. * Interface that all fields handlers must implement.
@ -42,7 +43,7 @@ export interface AddonModDataFieldHandler extends CoreDelegateHandler {
* @param field The field object. * @param field The field object.
* @return The component to use, undefined if not found. * @return The component to use, undefined if not found.
*/ */
getComponent?(plugin: AddonModDataField): Type<unknown> | undefined; getComponent?(plugin: AddonModDataField): Type<AddonModDataFieldPluginBaseComponent> | undefined;
/** /**
* Get field search data in the input data. * Get field search data in the input data.
@ -140,7 +141,7 @@ export class AddonModDataFieldsDelegateService extends CoreDelegate<AddonModData
* @param field The field object. * @param field The field object.
* @return Promise resolved with the component to use, undefined if not found. * @return Promise resolved with the component to use, undefined if not found.
*/ */
getComponentForField(field: AddonModDataField): Promise<Type<unknown> | undefined> { getComponentForField(field: AddonModDataField): Promise<Type<AddonModDataFieldPluginBaseComponent> | undefined> {
return Promise.resolve(this.executeFunctionOnEnabled(field.type, 'getComponent', [field])); return Promise.resolve(this.executeFunctionOnEnabled(field.type, 'getComponent', [field]));
} }

View File

@ -12,6 +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 { InstanceMethodParams, InstanceMethodReturn } from '@/core/utils/inference';
import { import {
Component, Component,
Input, Input,
@ -64,9 +65,9 @@ import { CoreLogger } from '@singletons/logger';
templateUrl: 'core-dynamic-component.html', templateUrl: 'core-dynamic-component.html',
styles: [':host { display: contents; }'], styles: [':host { display: contents; }'],
}) })
export class CoreDynamicComponent implements OnChanges, DoCheck { export class CoreDynamicComponent<ComponentClass> implements OnChanges, DoCheck {
@Input() component?: Type<unknown>; @Input() component?: Type<ComponentClass>;
@Input() data?: Record<string | number, unknown>; @Input() data?: Record<string | number, unknown>;
// Get the container where to put the dynamic component. // Get the container where to put the dynamic component.
@ -126,16 +127,21 @@ export class CoreDynamicComponent implements OnChanges, DoCheck {
} }
/** /**
* Call a certain function on the component. * Call a certain method on the component.
* *
* @param name Name of the function to call. * @param method Name of the method to call.
* @param params List of params to send to the function. * @param params List of params to send to the method.
* @return Result of the call. Undefined if no component instance or the function doesn't exist. * @return Result of the call. Undefined if the component instance is not ready.
*/ */
callComponentFunction<T = unknown>(name: string, params?: unknown[]): T | undefined { callComponentMethod<Method extends keyof ComponentClass>(
if (this.instance && typeof this.instance[name] == 'function') { method: Method,
return this.instance[name].apply(this.instance, params); ...params: InstanceMethodParams<ComponentClass, Method>
): InstanceMethodReturn<ComponentClass, Method> | undefined {
if (typeof this.instance?.[method] !== 'function') {
return;
} }
return this.instance[method].apply(this.instance, params);
} }
/** /**

View File

@ -105,7 +105,7 @@ export abstract class CoreBlockBaseComponent implements OnInit {
* *
* @return Resolved when done. * @return Resolved when done.
*/ */
protected async invalidateContent(): Promise<void> { async invalidateContent(): Promise<void> {
return; return;
} }

View File

@ -18,6 +18,7 @@ import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-comp
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { CoreCourseBlock } from '@/core/features/course/services/course'; import { CoreCourseBlock } from '@/core/features/course/services/course';
import { IonRefresher } from '@ionic/angular'; import { IonRefresher } from '@ionic/angular';
import type { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
/** /**
* Component to render a block. * Component to render a block.
@ -29,7 +30,7 @@ import { IonRefresher } from '@ionic/angular';
}) })
export class CoreBlockComponent implements OnInit, OnDestroy, DoCheck { export class CoreBlockComponent implements OnInit, OnDestroy, DoCheck {
@ViewChild(CoreDynamicComponent) dynamicComponent?: CoreDynamicComponent; @ViewChild(CoreDynamicComponent) dynamicComponent?: CoreDynamicComponent<CoreBlockBaseComponent>;
@Input() block!: CoreCourseBlock; // The block to render. @Input() block!: CoreCourseBlock; // The block to render.
@Input() contextLevel!: string; // The context where the block will be used. @Input() contextLevel!: string; // The context where the block will be used.
@ -146,7 +147,7 @@ export class CoreBlockComponent implements OnInit, OnDestroy, DoCheck {
showErrors: boolean = false, showErrors: boolean = false,
): Promise<void> { ): Promise<void> {
if (this.dynamicComponent) { if (this.dynamicComponent) {
await this.dynamicComponent.callComponentFunction('doRefresh', [refresher, done, showErrors]); await this.dynamicComponent.callComponentMethod('doRefresh', refresher, done, showErrors);
} }
} }
@ -157,7 +158,7 @@ export class CoreBlockComponent implements OnInit, OnDestroy, DoCheck {
*/ */
async invalidate(): Promise<void> { async invalidate(): Promise<void> {
if (this.dynamicComponent) { if (this.dynamicComponent) {
await this.dynamicComponent.callComponentFunction('invalidateContent'); await this.dynamicComponent.callComponentMethod('invalidateContent');
} }
} }

View File

@ -22,6 +22,7 @@ import { Params } from '@angular/router';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreBlockDefaultHandler } from './handlers/default-block'; import { CoreBlockDefaultHandler } from './handlers/default-block';
import { CoreNavigationOptions } from '@services/navigator'; import { CoreNavigationOptions } from '@services/navigator';
import type { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
/** /**
* Interface that all blocks must implement. * Interface that all blocks must implement.
@ -65,7 +66,7 @@ export interface CoreBlockHandlerData {
* The component to render the contents of the block. * The component to render the contents of the block.
* It's recommended to return the class of the component, but you can also return an instance of the component. * It's recommended to return the class of the component, but you can also return an instance of the component.
*/ */
component: Type<unknown>; component: Type<CoreBlockBaseComponent>;
/** /**
* Data to pass to the component. All the properties in this object will be passed to the component as inputs. * Data to pass to the component. All the properties in this object will be passed to the component as inputs.

View File

@ -78,7 +78,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
@Input() initialSectionNumber?: number; // The section to load first (by number). @Input() initialSectionNumber?: number; // The section to load first (by number).
@Input() moduleId?: number; // The module ID to scroll to. Must be inside the initial selected section. @Input() moduleId?: number; // The module ID to scroll to. Must be inside the initial selected section.
@ViewChildren(CoreDynamicComponent) dynamicComponents?: QueryList<CoreDynamicComponent>; @ViewChildren(CoreDynamicComponent) dynamicComponents?: QueryList<CoreDynamicComponent<any>>;
// All the possible component classes. // All the possible component classes.
courseFormatComponent?: Type<unknown>; courseFormatComponent?: Type<unknown>;
@ -567,7 +567,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
*/ */
async doRefresh(refresher?: IonRefresher, done?: () => void, afterCompletionChange?: boolean): Promise<void> { async doRefresh(refresher?: IonRefresher, done?: () => void, afterCompletionChange?: boolean): Promise<void> {
const promises = this.dynamicComponents?.map(async (component) => { const promises = this.dynamicComponents?.map(async (component) => {
await component.callComponentFunction('doRefresh', [refresher, done, afterCompletionChange]); await component.callComponentMethod('doRefresh', refresher, done, afterCompletionChange);
}) || []; }) || [];
if (this.course) { if (this.course) {
@ -640,7 +640,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
*/ */
ionViewDidEnter(): void { ionViewDidEnter(): void {
this.dynamicComponents?.forEach((component) => { this.dynamicComponents?.forEach((component) => {
component.callComponentFunction('ionViewDidEnter'); component.callComponentMethod('ionViewDidEnter');
}); });
} }
@ -649,7 +649,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
*/ */
ionViewDidLeave(): void { ionViewDidLeave(): void {
this.dynamicComponents?.forEach((component) => { this.dynamicComponents?.forEach((component) => {
component.callComponentFunction('ionViewDidLeave'); component.callComponentMethod('ionViewDidLeave');
}); });
} }

View File

@ -21,6 +21,7 @@ import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
import { IonRefresher } from '@ionic/angular'; import { IonRefresher } from '@ionic/angular';
import { CoreCourseModuleCompletionData, CoreCourseSection } from '@features/course/services/course-helper'; import { CoreCourseModuleCompletionData, CoreCourseSection } from '@features/course/services/course-helper';
import { CoreCourse } from '@features/course/services/course'; import { CoreCourse } from '@features/course/services/course';
import type { CoreCourseModuleMainActivityComponent } from '@features/course/classes/main-activity-component';
/** /**
* Component to display single activity format. It will determine the right component to use and instantiate it. * Component to display single activity format. It will determine the right component to use and instantiate it.
@ -41,7 +42,7 @@ export class CoreCourseFormatSingleActivityComponent implements OnChanges {
@Input() moduleId?: number; // The module ID to scroll to. Must be inside the initial selected section. @Input() moduleId?: number; // The module ID to scroll to. Must be inside the initial selected section.
@Output() completionChanged = new EventEmitter<CoreCourseModuleCompletionData>(); // Notify when any module completion changes. @Output() completionChanged = new EventEmitter<CoreCourseModuleCompletionData>(); // Notify when any module completion changes.
@ViewChild(CoreDynamicComponent) dynamicComponent?: CoreDynamicComponent; @ViewChild(CoreDynamicComponent) dynamicComponent?: CoreDynamicComponent<CoreCourseModuleMainActivityComponent>;
componentClass?: Type<unknown>; // The class of the component to render. componentClass?: Type<unknown>; // The class of the component to render.
data: Record<string | number, unknown> = {}; // Data to pass to the component. data: Record<string | number, unknown> = {}; // Data to pass to the component.
@ -85,7 +86,7 @@ export class CoreCourseFormatSingleActivityComponent implements OnChanges {
return; return;
} }
await this.dynamicComponent?.callComponentFunction('doRefresh', [refresher, done]); await this.dynamicComponent?.callComponentMethod('doRefresh', refresher);
if (this.course) { if (this.course) {
const courseId = this.course.id; const courseId = this.course.id;
@ -97,14 +98,14 @@ export class CoreCourseFormatSingleActivityComponent implements OnChanges {
* User entered the page that contains the component. * User entered the page that contains the component.
*/ */
ionViewDidEnter(): void { ionViewDidEnter(): void {
this.dynamicComponent?.callComponentFunction('ionViewDidEnter'); this.dynamicComponent?.callComponentMethod('ionViewDidEnter');
} }
/** /**
* User left the page that contains the component. * User left the page that contains the component.
*/ */
ionViewDidLeave(): void { ionViewDidLeave(): void {
this.dynamicComponent?.callComponentFunction('ionViewDidLeave'); this.dynamicComponent?.callComponentMethod('ionViewDidLeave');
} }
} }

View File

@ -18,6 +18,7 @@ import { AddonModAssignDefaultFeedbackHandler } from '@addons/mod/assign/service
import { AddonModAssignPlugin } from '@addons/mod/assign/services/assign'; import { AddonModAssignPlugin } from '@addons/mod/assign/services/assign';
import { CoreSitePluginsAssignFeedbackComponent } from '@features/siteplugins/components/assign-feedback/assign-feedback'; import { CoreSitePluginsAssignFeedbackComponent } from '@features/siteplugins/components/assign-feedback/assign-feedback';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import type{ IAddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
/** /**
* Handler to display an assign feedback site plugin. * Handler to display an assign feedback site plugin.
@ -31,7 +32,7 @@ export class CoreSitePluginsAssignFeedbackHandler extends AddonModAssignDefaultF
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown> | undefined { getComponent(): Type<IAddonModAssignFeedbackPluginComponent> | undefined {
return CoreSitePluginsAssignFeedbackComponent; return CoreSitePluginsAssignFeedbackComponent;
} }

View File

@ -18,6 +18,7 @@ import { AddonModAssignPlugin } from '@addons/mod/assign/services/assign';
import { AddonModAssignDefaultSubmissionHandler } from '@addons/mod/assign/services/handlers/default-submission'; import { AddonModAssignDefaultSubmissionHandler } from '@addons/mod/assign/services/handlers/default-submission';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import { CoreSitePluginsAssignSubmissionComponent } from '../../components/assign-submission/assign-submission'; import { CoreSitePluginsAssignSubmissionComponent } from '../../components/assign-submission/assign-submission';
import type { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
/** /**
* Handler to display an assign submission site plugin. * Handler to display an assign submission site plugin.
@ -31,7 +32,7 @@ export class CoreSitePluginsAssignSubmissionHandler extends AddonModAssignDefaul
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown> { getComponent(): Type<AddonModAssignSubmissionPluginBaseComponent> {
return CoreSitePluginsAssignSubmissionComponent; return CoreSitePluginsAssignSubmissionComponent;
} }

View File

@ -14,6 +14,7 @@
import { Type } from '@angular/core'; import { Type } from '@angular/core';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
import type { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
import { CoreBlockPreRenderedComponent } from '@features/block/components/pre-rendered-block/pre-rendered-block'; import { CoreBlockPreRenderedComponent } from '@features/block/components/pre-rendered-block/pre-rendered-block';
import { CoreBlockDelegate, CoreBlockHandler, CoreBlockHandlerData } from '@features/block/services/block-delegate'; import { CoreBlockDelegate, CoreBlockHandler, CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreCourseBlock } from '@features/course/services/course'; import { CoreCourseBlock } from '@features/course/services/course';
@ -51,7 +52,7 @@ export class CoreSitePluginsBlockHandler extends CoreSitePluginsBaseHandler impl
instanceId: number, instanceId: number,
): Promise<CoreBlockHandlerData> { ): Promise<CoreBlockHandlerData> {
const className = this.handlerSchema.displaydata?.class || 'block_' + block.name; const className = this.handlerSchema.displaydata?.class || 'block_' + block.name;
let component: Type<unknown> | undefined; let component: Type<CoreBlockBaseComponent> | undefined;
if (this.handlerSchema.displaydata?.type == 'title') { if (this.handlerSchema.displaydata?.type == 'title') {
component = CoreSitePluginsOnlyTitleBlockComponent; component = CoreSitePluginsOnlyTitleBlockComponent;

View File

@ -70,7 +70,7 @@ export class CoreSitePluginsBlockComponent extends CoreBlockBaseComponent implem
* *
* @return Promise resolved when done. * @return Promise resolved when done.
*/ */
protected async invalidateContent(): Promise<void> { async invalidateContent(): Promise<void> {
if (!this.component || !this.method) { if (!this.component || !this.method) {
return; return;
} }

27
src/core/utils/inference.d.ts vendored 100644
View File

@ -0,0 +1,27 @@
// (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.
/**
* Get instance method params type.
*/
export type InstanceMethodParams<InstanceClass, Method extends keyof InstanceClass> =
// eslint-disable-next-line @typescript-eslint/no-explicit-any
InstanceClass[Method] extends (...args: infer Args) => any ? Args : never;
/**
* Get instance method return type.
*/
export type InstanceMethodReturn<InstanceClass, Method extends keyof InstanceClass> =
// eslint-disable-next-line @typescript-eslint/no-explicit-any
InstanceClass[Method] extends (...args: any[]) => infer R ? R : never;