3
0

Merge pull request from NoelDeMartin/MOBILE-3942

MOBILE-3942 core: Improve dynamic component calls
This commit is contained in:
Dani Palou 2022-06-23 09:38:10 +02:00 committed by GitHub
commit e7bd014848
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 179 additions and 96 deletions
src
addons
block
activitymodules/components/activitymodules
myoverview/components/myoverview
recentlyaccessedcourses/components/recentlyaccessedcourses
recentlyaccesseditems/components/recentlyaccesseditems
sitemainmenu/components/sitemainmenu
starredcourses/components/starredcourses
timeline/components/timeline
mod
assign
classes
components
feedback-plugin
submission-plugin
feedback
comments/services
editpdf/services
file/services
services
submission
comments/services
file/services
onlinetext/services
data
classes
components/field-plugin
fields
checkbox
component
services
date
component
services
file
component
services
latlong
component
services
menu
component
services
multimenu
component
services
number
component
services
picture
component
services
radiobutton
component
services
text
component
services
textarea
component
services
url
component
services
pages/edit
services
core
components/dynamic-component
features
block
course
components/course-format
format/singleactivity/components
siteplugins
utils

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

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

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

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

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

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

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

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

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// 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 { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component';
import { CoreWSFile } from '@services/ws';
@ -34,7 +35,7 @@ import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate
})
export class AddonModAssignFeedbackPluginComponent implements OnInit {
@ViewChild(CoreDynamicComponent) dynamicComponent!: CoreDynamicComponent;
@ViewChild(CoreDynamicComponent) dynamicComponent!: CoreDynamicComponent<IAddonModAssignFeedbackPluginComponent>;
@Input() assign!: AddonModAssignAssign; // The assignment.
@Input() submission!: AddonModAssignSubmission; // The submission.
@ -43,7 +44,7 @@ export class AddonModAssignFeedbackPluginComponent implements OnInit {
@Input() canEdit = false; // Whether the user can edit.
@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 to render the plugin if it isn't supported.
@ -101,7 +102,7 @@ export class AddonModAssignFeedbackPluginComponent implements OnInit {
* @return Promise resolved when done.
*/
async invalidate(): Promise<void> {
await this.dynamicComponent.callComponentFunction('invalidate', []);
await this.dynamicComponent.callComponentMethod('invalidate');
}
}

@ -24,6 +24,7 @@ import {
import { AddonModAssignHelper, AddonModAssignPluginConfig } from '../../services/assign-helper';
import { AddonModAssignSubmissionDelegate } from '../../services/submission-delegate';
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.
@ -34,7 +35,7 @@ import { CoreFileEntry } from '@services/file-helper';
})
export class AddonModAssignSubmissionPluginComponent implements OnInit {
@ViewChild(CoreDynamicComponent) dynamicComponent!: CoreDynamicComponent;
@ViewChild(CoreDynamicComponent) dynamicComponent!: CoreDynamicComponent<AddonModAssignSubmissionPluginBaseComponent>;
@Input() assign!: AddonModAssignAssign; // The assignment.
@Input() submission!: AddonModAssignSubmission; // The submission.
@ -42,7 +43,7 @@ export class AddonModAssignSubmissionPluginComponent implements OnInit {
@Input() edit = false; // Whether the user is editing.
@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 to render the plugin if it isn't supported.
@ -99,7 +100,7 @@ export class AddonModAssignSubmissionPluginComponent implements OnInit {
* @return Promise resolved when done.
*/
async invalidate(): Promise<void> {
await this.dynamicComponent.callComponentFunction('invalidate', []);
await this.dynamicComponent.callComponentMethod('invalidate');
}
}

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import type { IAddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
import {
AddonModAssignPlugin,
AddonModAssignAssign,
@ -80,7 +81,7 @@ export class AddonModAssignFeedbackCommentsHandlerService implements AddonModAss
*
* @return The component (or promise resolved with component) to use, undefined if not found.
*/
getComponent(): Type<unknown> {
getComponent(): Type<IAddonModAssignFeedbackPluginComponent> {
return AddonModAssignFeedbackCommentsComponent;
}

@ -23,6 +23,7 @@ import { Injectable, Type } from '@angular/core';
import { CoreWSFile } from '@services/ws';
import { makeSingleton } from '@singletons';
import { AddonModAssignFeedbackEditPdfComponent } from '../component/editpdf';
import type { IAddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
/**
* 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.
*/
getComponent(): Type<unknown> {
getComponent(): Type<IAddonModAssignFeedbackPluginComponent> {
return AddonModAssignFeedbackEditPdfComponent;
}

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import type { IAddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
import {
AddonModAssignPlugin,
AddonModAssignAssign,
@ -39,7 +40,7 @@ export class AddonModAssignFeedbackFileHandlerService implements AddonModAssignF
*
* @return The component (or promise resolved with component) to use, undefined if not found.
*/
getComponent(): Type<unknown> {
getComponent(): Type<IAddonModAssignFeedbackPluginComponent> {
return AddonModAssignFeedbackFileComponent;
}

@ -20,6 +20,7 @@ import { makeSingleton } from '@singletons';
import { CoreWSFile } from '@services/ws';
import { AddonModAssignSubmissionFormatted } from './assign-helper';
import { CoreFormFields } from '@singletons/form';
import type { IAddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
/**
* Interface that all feedback handlers must implement.
@ -48,7 +49,9 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler {
* @param plugin The plugin object.
* @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.
@ -209,7 +212,9 @@ export class AddonModAssignFeedbackDelegateService extends CoreDelegate<AddonMod
* @param plugin The plugin object.
* @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]);
}

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

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// 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 { AddonModAssignSubmissionHandler } from '@addons/mod/assign/services/submission-delegate';
import { Injectable, Type } from '@angular/core';
@ -48,7 +49,7 @@ export class AddonModAssignSubmissionCommentsHandlerService implements AddonModA
* @param edit Whether the user is editing.
* @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;
}

@ -31,6 +31,7 @@ import { CoreWSFile } from '@services/ws';
import { makeSingleton } from '@singletons';
import { AddonModAssignSubmissionFileComponent } from '../component/file';
import { FileEntry } from '@ionic-native/file/ngx';
import type { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
/**
* 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.
*/
getComponent(): Type<unknown> {
getComponent(): Type<AddonModAssignSubmissionPluginBaseComponent> {
return AddonModAssignSubmissionFileComponent;
}

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import type { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
import {
AddonModAssignAssign,
AddonModAssignSubmission,
@ -106,7 +107,7 @@ export class AddonModAssignSubmissionOnlineTextHandlerService implements AddonMo
*
* @return The component (or promise resolved with component) to use, undefined if not found.
*/
getComponent(): Type<unknown> {
getComponent(): Type<AddonModAssignSubmissionPluginBaseComponent> {
return AddonModAssignSubmissionOnlineTextComponent;
}

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

@ -16,7 +16,7 @@ import { Component, OnInit, OnChanges, ViewChild, Input, Output, SimpleChange, T
import { FormGroup } from '@angular/forms';
import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component';
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 { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
@ -29,7 +29,7 @@ import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate'
})
export class AddonModDataFieldPluginComponent implements OnInit, OnChanges {
@ViewChild(CoreDynamicComponent) dynamicComponent?: CoreDynamicComponent;
@ViewChild(CoreDynamicComponent) dynamicComponent?: CoreDynamicComponent<AddonModDataFieldPluginBaseComponent>;
@Input() mode!: AddonModDataTemplateMode; // The render mode.
@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() 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.
fieldLoaded = false;

@ -14,7 +14,7 @@
import { AddonModDataEntryField } from '@addons/mod/data/services/data';
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.
@ -23,7 +23,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-checkbox',
templateUrl: 'addon-mod-data-field-checkbox.html',
})
export class AddonModDataFieldCheckboxComponent extends AddonModDataFieldPluginComponent {
export class AddonModDataFieldCheckboxComponent extends AddonModDataFieldPluginBaseComponent {
options: {
key: string;

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

@ -15,7 +15,7 @@
import { Component } from '@angular/core';
import { CoreTimeUtils } from '@services/utils/time';
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.
@ -24,7 +24,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-date',
templateUrl: 'addon-mod-data-field-date.html',
})
export class AddonModDataFieldDateComponent extends AddonModDataFieldPluginComponent {
export class AddonModDataFieldDateComponent extends AddonModDataFieldPluginBaseComponent {
format!: string;
displayDate?: number;

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

@ -13,7 +13,7 @@
// limitations under the License.
import { Component } from '@angular/core';
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 { CoreFileEntry } from '@services/file-helper';
@ -24,7 +24,7 @@ import { CoreFileEntry } from '@services/file-helper';
selector: 'addon-mod-data-field-file',
templateUrl: 'addon-mod-data-field-file.html',
})
export class AddonModDataFieldFileComponent extends AddonModDataFieldPluginComponent {
export class AddonModDataFieldFileComponent extends AddonModDataFieldPluginBaseComponent {
files: CoreFileEntry[] = [];
component?: string;

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

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// 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 { Component } from '@angular/core';
import { FormBuilder } from '@angular/forms';
@ -30,7 +30,7 @@ import { DomSanitizer } from '@singletons';
selector: 'addon-mod-data-field-latlong',
templateUrl: 'addon-mod-data-field-latlong.html',
})
export class AddonModDataFieldLatlongComponent extends AddonModDataFieldPluginComponent {
export class AddonModDataFieldLatlongComponent extends AddonModDataFieldPluginBaseComponent {
north?: number;
east?: number;

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

@ -13,7 +13,7 @@
// limitations under the License.
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.
@ -22,7 +22,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-menu',
templateUrl: 'addon-mod-data-field-menu.html',
})
export class AddonModDataFieldMenuComponent extends AddonModDataFieldPluginComponent {
export class AddonModDataFieldMenuComponent extends AddonModDataFieldPluginBaseComponent {
options: string[] = [];

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

@ -14,7 +14,7 @@
import { AddonModDataEntryField } from '@addons/mod/data/services/data';
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.
@ -23,7 +23,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-multimenu',
templateUrl: 'addon-mod-data-field-multimenu.html',
})
export class AddonModDataFieldMultimenuComponent extends AddonModDataFieldPluginComponent {
export class AddonModDataFieldMultimenuComponent extends AddonModDataFieldPluginBaseComponent {
options: {
key: string;

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

@ -13,7 +13,7 @@
// limitations under the License.
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.
@ -22,7 +22,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-number',
templateUrl: 'addon-mod-data-field-number.html',
})
export class AddonModDataFieldNumberComponent extends AddonModDataFieldPluginComponent{
export class AddonModDataFieldNumberComponent extends AddonModDataFieldPluginBaseComponent{
/**
* @inheritdoc

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

@ -16,7 +16,7 @@ import { Component } from '@angular/core';
import { CoreFileEntry, CoreFileHelper } from '@services/file-helper';
import { CoreFileSession } from '@services/file-session';
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.
@ -25,7 +25,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-picture',
templateUrl: 'addon-mod-data-field-picture.html',
})
export class AddonModDataFieldPictureComponent extends AddonModDataFieldPluginComponent {
export class AddonModDataFieldPictureComponent extends AddonModDataFieldPluginBaseComponent {
files: CoreFileEntry[] = [];
component?: string;

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

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
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.
@ -21,7 +21,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-radiobutton',
templateUrl: 'addon-mod-data-field-radiobutton.html',
})
export class AddonModDataFieldRadiobuttonComponent extends AddonModDataFieldPluginComponent {
export class AddonModDataFieldRadiobuttonComponent extends AddonModDataFieldPluginBaseComponent {
options: string[] = [];

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

@ -13,7 +13,7 @@
// limitations under the License.
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.
@ -22,7 +22,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-text',
templateUrl: 'addon-mod-data-field-text.html',
})
export class AddonModDataFieldTextComponent extends AddonModDataFieldPluginComponent {
export class AddonModDataFieldTextComponent extends AddonModDataFieldPluginBaseComponent {
/**
* @inheritdoc

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

@ -13,7 +13,7 @@
// limitations under the License.
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 { CoreTextUtils } from '@services/utils/text';
import { CoreWSFile } from '@services/ws';
@ -25,7 +25,7 @@ import { CoreWSFile } from '@services/ws';
selector: 'addon-mod-data-field-textarea',
templateUrl: 'addon-mod-data-field-textarea.html',
})
export class AddonModDataFieldTextareaComponent extends AddonModDataFieldPluginComponent {
export class AddonModDataFieldTextareaComponent extends AddonModDataFieldPluginBaseComponent {
component?: string;
componentId?: number;

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

@ -13,7 +13,7 @@
// limitations under the License.
import { AddonModDataEntryField } from '@addons/mod/data/services/data';
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.
@ -22,7 +22,7 @@ import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-
selector: 'addon-mod-data-field-url',
templateUrl: 'addon-mod-data-field-url.html',
})
export class AddonModDataFieldUrlComponent extends AddonModDataFieldPluginComponent {
export class AddonModDataFieldUrlComponent extends AddonModDataFieldPluginBaseComponent {
autoLink = false;
displayValue = '';

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

@ -41,7 +41,7 @@ import {
} from '../../services/data';
import { AddonModDataHelper } from '../../services/data-helper';
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.

@ -24,6 +24,7 @@ import { AddonModDataEntryField,
import { CoreFormFields } from '@singletons/form';
import { FileEntry } from '@ionic-native/file/ngx';
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.
@ -42,7 +43,7 @@ export interface AddonModDataFieldHandler extends CoreDelegateHandler {
* @param field The field object.
* @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.
@ -140,7 +141,7 @@ export class AddonModDataFieldsDelegateService extends CoreDelegate<AddonModData
* @param field The field object.
* @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]));
}

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { InstanceMethodParams, InstanceMethodReturn } from '@/core/utils/inference';
import {
Component,
Input,
@ -64,9 +65,9 @@ import { CoreLogger } from '@singletons/logger';
templateUrl: 'core-dynamic-component.html',
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>;
// 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 params List of params to send to the function.
* @return Result of the call. Undefined if no component instance or the function doesn't exist.
* @param method Name of the method to call.
* @param params List of params to send to the method.
* @return Result of the call. Undefined if the component instance is not ready.
*/
callComponentFunction<T = unknown>(name: string, params?: unknown[]): T | undefined {
if (this.instance && typeof this.instance[name] == 'function') {
return this.instance[name].apply(this.instance, params);
callComponentMethod<Method extends keyof ComponentClass>(
method: Method,
...params: InstanceMethodParams<ComponentClass, Method>
): InstanceMethodReturn<ComponentClass, Method> | undefined {
if (typeof this.instance?.[method] !== 'function') {
return;
}
return this.instance[method].apply(this.instance, params);
}
/**

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

@ -18,6 +18,7 @@ import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-comp
import { Subscription } from 'rxjs';
import { CoreCourseBlock } from '@/core/features/course/services/course';
import { IonRefresher } from '@ionic/angular';
import type { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
/**
* Component to render a block.
@ -29,7 +30,7 @@ import { IonRefresher } from '@ionic/angular';
})
export class CoreBlockComponent implements OnInit, OnDestroy, DoCheck {
@ViewChild(CoreDynamicComponent) dynamicComponent?: CoreDynamicComponent;
@ViewChild(CoreDynamicComponent) dynamicComponent?: CoreDynamicComponent<CoreBlockBaseComponent>;
@Input() block!: CoreCourseBlock; // The block to render.
@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,
): Promise<void> {
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> {
if (this.dynamicComponent) {
await this.dynamicComponent.callComponentFunction('invalidateContent');
await this.dynamicComponent.callComponentMethod('invalidateContent');
}
}

@ -22,6 +22,7 @@ import { Params } from '@angular/router';
import { makeSingleton } from '@singletons';
import { CoreBlockDefaultHandler } from './handlers/default-block';
import { CoreNavigationOptions } from '@services/navigator';
import type { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
/**
* Interface that all blocks must implement.
@ -65,7 +66,7 @@ export interface CoreBlockHandlerData {
* 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.
*/
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.

@ -78,7 +78,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
@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.
@ViewChildren(CoreDynamicComponent) dynamicComponents?: QueryList<CoreDynamicComponent>;
@ViewChildren(CoreDynamicComponent) dynamicComponents?: QueryList<CoreDynamicComponent<any>>;
// All the possible component classes.
courseFormatComponent?: Type<unknown>;
@ -567,7 +567,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
*/
async doRefresh(refresher?: IonRefresher, done?: () => void, afterCompletionChange?: boolean): Promise<void> {
const promises = this.dynamicComponents?.map(async (component) => {
await component.callComponentFunction('doRefresh', [refresher, done, afterCompletionChange]);
await component.callComponentMethod('doRefresh', refresher, done, afterCompletionChange);
}) || [];
if (this.course) {
@ -640,7 +640,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
*/
ionViewDidEnter(): void {
this.dynamicComponents?.forEach((component) => {
component.callComponentFunction('ionViewDidEnter');
component.callComponentMethod('ionViewDidEnter');
});
}
@ -649,7 +649,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
*/
ionViewDidLeave(): void {
this.dynamicComponents?.forEach((component) => {
component.callComponentFunction('ionViewDidLeave');
component.callComponentMethod('ionViewDidLeave');
});
}

@ -21,6 +21,7 @@ import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
import { IonRefresher } from '@ionic/angular';
import { CoreCourseModuleCompletionData, CoreCourseSection } from '@features/course/services/course-helper';
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.
@ -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.
@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.
data: Record<string | number, unknown> = {}; // Data to pass to the component.
@ -85,7 +86,7 @@ export class CoreCourseFormatSingleActivityComponent implements OnChanges {
return;
}
await this.dynamicComponent?.callComponentFunction('doRefresh', [refresher, done]);
await this.dynamicComponent?.callComponentMethod('doRefresh', refresher);
if (this.course) {
const courseId = this.course.id;
@ -97,14 +98,14 @@ export class CoreCourseFormatSingleActivityComponent implements OnChanges {
* User entered the page that contains the component.
*/
ionViewDidEnter(): void {
this.dynamicComponent?.callComponentFunction('ionViewDidEnter');
this.dynamicComponent?.callComponentMethod('ionViewDidEnter');
}
/**
* User left the page that contains the component.
*/
ionViewDidLeave(): void {
this.dynamicComponent?.callComponentFunction('ionViewDidLeave');
this.dynamicComponent?.callComponentMethod('ionViewDidLeave');
}
}

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

@ -18,6 +18,7 @@ import { AddonModAssignPlugin } from '@addons/mod/assign/services/assign';
import { AddonModAssignDefaultSubmissionHandler } from '@addons/mod/assign/services/handlers/default-submission';
import { Translate } from '@singletons';
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.
@ -31,7 +32,7 @@ export class CoreSitePluginsAssignSubmissionHandler extends AddonModAssignDefaul
/**
* @inheritdoc
*/
getComponent(): Type<unknown> {
getComponent(): Type<AddonModAssignSubmissionPluginBaseComponent> {
return CoreSitePluginsAssignSubmissionComponent;
}

@ -14,6 +14,7 @@
import { Type } from '@angular/core';
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 { CoreBlockDelegate, CoreBlockHandler, CoreBlockHandlerData } from '@features/block/services/block-delegate';
import { CoreCourseBlock } from '@features/course/services/course';
@ -51,7 +52,7 @@ export class CoreSitePluginsBlockHandler extends CoreSitePluginsBaseHandler impl
instanceId: number,
): Promise<CoreBlockHandlerData> {
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') {
component = CoreSitePluginsOnlyTitleBlockComponent;

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

27
src/core/utils/inference.d.ts vendored Normal 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;