forked from CIT/Vmeda.Online
		
	MOBILE-3664 siteplugins: Implement components
This commit is contained in:
		
							parent
							
								
									99b665915b
								
							
						
					
					
						commit
						1659df55cb
					
				@ -32,6 +32,9 @@ export class AddonQbehaviourDeferredCBMComponent {
 | 
				
			|||||||
    @Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
 | 
					    @Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
 | 
				
			||||||
    @Input() contextLevel?: string; // The context level.
 | 
					    @Input() contextLevel?: string; // The context level.
 | 
				
			||||||
    @Input() contextInstanceId?: number; // The instance ID related to the context.
 | 
					    @Input() contextInstanceId?: number; // The instance ID related to the context.
 | 
				
			||||||
 | 
					    @Input() courseId?: number; // Course ID the question belongs to (if any). It can be used to improve performance with filters.
 | 
				
			||||||
 | 
					    @Input() review?: boolean; // Whether the user is in review mode.
 | 
				
			||||||
 | 
					    @Input() preferredBehaviour?: string; // Preferred behaviour.
 | 
				
			||||||
    @Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
 | 
					    @Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
 | 
				
			||||||
    @Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
 | 
					    @Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -32,6 +32,9 @@ export class AddonQbehaviourInformationItemComponent {
 | 
				
			|||||||
    @Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
 | 
					    @Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
 | 
				
			||||||
    @Input() contextLevel?: string; // The context level.
 | 
					    @Input() contextLevel?: string; // The context level.
 | 
				
			||||||
    @Input() contextInstanceId?: number; // The instance ID related to the context.
 | 
					    @Input() contextInstanceId?: number; // The instance ID related to the context.
 | 
				
			||||||
 | 
					    @Input() courseId?: number; // Course ID the question belongs to (if any). It can be used to improve performance with filters.
 | 
				
			||||||
 | 
					    @Input() review?: boolean; // Whether the user is in review mode.
 | 
				
			||||||
 | 
					    @Input() preferredBehaviour?: string; // Preferred behaviour.
 | 
				
			||||||
    @Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
 | 
					    @Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
 | 
				
			||||||
    @Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
 | 
					    @Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -507,6 +507,9 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await Promise.all(promises);
 | 
					        await Promise.all(promises);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        refresher?.detail.complete();
 | 
				
			||||||
 | 
					        done?.();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,7 @@ export class CoreQuestionBaseComponent {
 | 
				
			|||||||
    @Input() contextInstanceId?: number; // The instance ID related to the context.
 | 
					    @Input() contextInstanceId?: number; // The instance ID related to the context.
 | 
				
			||||||
    @Input() courseId?: number; // The course the question belongs to (if any).
 | 
					    @Input() courseId?: number; // The course the question belongs to (if any).
 | 
				
			||||||
    @Input() review?: boolean; // Whether the user is in review mode.
 | 
					    @Input() review?: boolean; // Whether the user is in review mode.
 | 
				
			||||||
 | 
					    @Input() preferredBehaviour?: string; // Preferred behaviour.
 | 
				
			||||||
    @Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
 | 
					    @Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
 | 
				
			||||||
    @Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
 | 
					    @Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -95,6 +95,7 @@ export class CoreQuestionComponent implements OnInit {
 | 
				
			|||||||
            contextInstanceId: this.contextInstanceId,
 | 
					            contextInstanceId: this.contextInstanceId,
 | 
				
			||||||
            courseId: this.courseId,
 | 
					            courseId: this.courseId,
 | 
				
			||||||
            review: this.review,
 | 
					            review: this.review,
 | 
				
			||||||
 | 
					            preferredBehaviour: this.preferredBehaviour,
 | 
				
			||||||
            buttonClicked: this.buttonClicked,
 | 
					            buttonClicked: this.buttonClicked,
 | 
				
			||||||
            onAbort: this.onAbort,
 | 
					            onAbort: this.onAbort,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					// (C) Copyright 2015 Moodle Pty Ltd.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Component, OnInit, Input } from '@angular/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '@addons/mod/assign/services/assign';
 | 
				
			||||||
 | 
					import { AddonModAssignFeedbackDelegate } from '@addons/mod/assign/services/feedback-delegate';
 | 
				
			||||||
 | 
					import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/classes/compile-init-component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component that displays an assign feedback plugin created using a site plugin.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'core-site-plugins-assign-feedback',
 | 
				
			||||||
 | 
					    templateUrl: 'core-siteplugins-assign-feedback.html',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CoreSitePluginsAssignFeedbackComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Input() assign!: AddonModAssignAssign; // The assignment.
 | 
				
			||||||
 | 
					    @Input() submission!: AddonModAssignSubmission; // The submission.
 | 
				
			||||||
 | 
					    @Input() plugin!: AddonModAssignPlugin; // The plugin object.
 | 
				
			||||||
 | 
					    @Input() userId!: number; // The user ID of the submission.
 | 
				
			||||||
 | 
					    @Input() canEdit = false; // Whether the user can edit.
 | 
				
			||||||
 | 
					    @Input() edit = false; // Whether the user is editing.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Component being initialized.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnInit(): void {
 | 
				
			||||||
 | 
					        // Pass the input and output data to the component.
 | 
				
			||||||
 | 
					        this.jsData.assign = this.assign;
 | 
				
			||||||
 | 
					        this.jsData.submission = this.submission;
 | 
				
			||||||
 | 
					        this.jsData.plugin = this.plugin;
 | 
				
			||||||
 | 
					        this.jsData.userId = this.userId;
 | 
				
			||||||
 | 
					        this.jsData.edit = this.edit;
 | 
				
			||||||
 | 
					        this.jsData.canEdit = this.canEdit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (this.plugin) {
 | 
				
			||||||
 | 
					            this.getHandlerData(AddonModAssignFeedbackDelegate.getHandlerName(this.plugin.type));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Invalidate the data.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Promise resolved when done.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    invalidate(): Promise<void> {
 | 
				
			||||||
 | 
					        return Promise.resolve();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>
 | 
				
			||||||
@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					// (C) Copyright 2015 Moodle Pty Ltd.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Component, OnInit, Input } from '@angular/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '@addons/mod/assign/services/assign';
 | 
				
			||||||
 | 
					import { AddonModAssignSubmissionDelegate } from '@addons/mod/assign/services/submission-delegate';
 | 
				
			||||||
 | 
					import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/classes/compile-init-component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component that displays an assign submission plugin created using a site plugin.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'core-site-plugins-assign-submission',
 | 
				
			||||||
 | 
					    templateUrl: 'core-siteplugins-assign-submission.html',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CoreSitePluginsAssignSubmissionComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Input() assign!: AddonModAssignAssign; // The assignment.
 | 
				
			||||||
 | 
					    @Input() submission!: AddonModAssignSubmission; // The submission.
 | 
				
			||||||
 | 
					    @Input() plugin!: AddonModAssignPlugin; // The plugin object.
 | 
				
			||||||
 | 
					    @Input() edit = false; // Whether the user is editing.
 | 
				
			||||||
 | 
					    @Input() allowOffline = false; // Whether to allow offline.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Component being initialized.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnInit(): void {
 | 
				
			||||||
 | 
					        // Pass the input and output data to the component.
 | 
				
			||||||
 | 
					        this.jsData.assign = this.assign;
 | 
				
			||||||
 | 
					        this.jsData.submission = this.submission;
 | 
				
			||||||
 | 
					        this.jsData.plugin = this.plugin;
 | 
				
			||||||
 | 
					        this.jsData.edit = this.edit;
 | 
				
			||||||
 | 
					        this.jsData.allowOffline = this.allowOffline;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (this.plugin) {
 | 
				
			||||||
 | 
					            this.getHandlerData(AddonModAssignSubmissionDelegate.getHandlerName(this.plugin.type));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Invalidate the data.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Promise resolved when done.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    invalidate(): Promise<void> {
 | 
				
			||||||
 | 
					        return Promise.resolve();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>
 | 
				
			||||||
							
								
								
									
										80
									
								
								src/core/features/siteplugins/components/block/block.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/core/features/siteplugins/components/block/block.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					// (C) Copyright 2015 Moodle Pty Ltd.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Component, OnChanges, ViewChild } from '@angular/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
 | 
				
			||||||
 | 
					import { CoreBlockDelegate } from '@features/block/services/block-delegate';
 | 
				
			||||||
 | 
					import { CoreSitePlugins, CoreSitePluginsContent } from '@features/siteplugins/services/siteplugins';
 | 
				
			||||||
 | 
					import { CoreSitePluginsPluginContentComponent } from '../plugin-content/plugin-content';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component that displays the index of a course format site plugin.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'core-site-plugins-block',
 | 
				
			||||||
 | 
					    templateUrl: 'core-siteplugins-block.html',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CoreSitePluginsBlockComponent extends CoreBlockBaseComponent implements OnChanges {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @ViewChild(CoreSitePluginsPluginContentComponent) content?: CoreSitePluginsPluginContentComponent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    component?: string;
 | 
				
			||||||
 | 
					    method?: string;
 | 
				
			||||||
 | 
					    args?: Record<string, unknown>;
 | 
				
			||||||
 | 
					    initResult?: CoreSitePluginsContent | null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor() {
 | 
				
			||||||
 | 
					        super('CoreSitePluginsBlockComponent');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Detect changes on input properties.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnChanges(): void {
 | 
				
			||||||
 | 
					        if (this.component) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Initialize the data.
 | 
				
			||||||
 | 
					        const handlerName = CoreBlockDelegate.getHandlerName(this.block.name);
 | 
				
			||||||
 | 
					        const handler = CoreSitePlugins.getSitePluginHandler(handlerName);
 | 
				
			||||||
 | 
					        if (!handler) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.component = handler.plugin.component;
 | 
				
			||||||
 | 
					        this.method = handler.handlerSchema.method;
 | 
				
			||||||
 | 
					        this.args = {
 | 
				
			||||||
 | 
					            contextlevel: this.contextLevel,
 | 
				
			||||||
 | 
					            instanceid: this.instanceId,
 | 
				
			||||||
 | 
					            blockid: this.block.instanceid,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        this.initResult = handler.initResult;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Invalidate block data.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Promise resolved when done.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected async invalidateContent(): Promise<void> {
 | 
				
			||||||
 | 
					        if (!this.component || !this.method) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return CoreSitePlugins.invalidateContent(this.component, this.method, this.args);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					<core-site-plugins-plugin-content *ngIf="component && method" [component]="component" [method]="method" [args]="args"
 | 
				
			||||||
 | 
					    [initResult]="initResult">
 | 
				
			||||||
 | 
					</core-site-plugins-plugin-content>
 | 
				
			||||||
@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					// (C) Copyright 2015 Moodle Pty Ltd.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { NgModule } from '@angular/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { CoreSharedModule } from '@/core/shared.module';
 | 
				
			||||||
 | 
					import { CoreCompileHtmlComponentModule } from '@features/compile/components/compile-html/compile-html.module';
 | 
				
			||||||
 | 
					import { CoreSitePluginsPluginContentComponent } from './plugin-content/plugin-content';
 | 
				
			||||||
 | 
					import { CoreSitePluginsModuleIndexComponent } from './module-index/module-index';
 | 
				
			||||||
 | 
					import { CoreSitePluginsCourseOptionComponent } from './course-option/course-option';
 | 
				
			||||||
 | 
					import { CoreSitePluginsCourseFormatComponent } from './course-format/course-format';
 | 
				
			||||||
 | 
					import { CoreSitePluginsUserProfileFieldComponent } from './user-profile-field/user-profile-field';
 | 
				
			||||||
 | 
					import { CoreSitePluginsQuestionComponent } from './question/question';
 | 
				
			||||||
 | 
					import { CoreSitePluginsQuestionBehaviourComponent } from './question-behaviour/question-behaviour';
 | 
				
			||||||
 | 
					import { CoreSitePluginsQuizAccessRuleComponent } from './quiz-access-rule/quiz-access-rule';
 | 
				
			||||||
 | 
					import { CoreSitePluginsAssignFeedbackComponent } from './assign-feedback/assign-feedback';
 | 
				
			||||||
 | 
					import { CoreSitePluginsAssignSubmissionComponent } from './assign-submission/assign-submission';
 | 
				
			||||||
 | 
					// @todo
 | 
				
			||||||
 | 
					// import { CoreSitePluginsWorkshopAssessmentStrategyComponent } from './workshop-assessment-strategy/workshop-assessment-strategy';
 | 
				
			||||||
 | 
					import { CoreSitePluginsBlockComponent } from './block/block';
 | 
				
			||||||
 | 
					import { CoreSitePluginsOnlyTitleBlockComponent } from './only-title-block/only-title-block';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@NgModule({
 | 
				
			||||||
 | 
					    declarations: [
 | 
				
			||||||
 | 
					        CoreSitePluginsPluginContentComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsModuleIndexComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsBlockComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsOnlyTitleBlockComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsCourseOptionComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsCourseFormatComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsUserProfileFieldComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsQuestionComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsQuestionBehaviourComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsQuizAccessRuleComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsAssignFeedbackComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsAssignSubmissionComponent,
 | 
				
			||||||
 | 
					        // @todo CoreSitePluginsWorkshopAssessmentStrategyComponent,
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    imports: [
 | 
				
			||||||
 | 
					        CoreSharedModule,
 | 
				
			||||||
 | 
					        CoreCompileHtmlComponentModule,
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    providers: [],
 | 
				
			||||||
 | 
					    exports: [
 | 
				
			||||||
 | 
					        CoreSitePluginsPluginContentComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsModuleIndexComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsBlockComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsOnlyTitleBlockComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsCourseOptionComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsCourseFormatComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsUserProfileFieldComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsQuestionComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsQuestionBehaviourComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsQuizAccessRuleComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsAssignFeedbackComponent,
 | 
				
			||||||
 | 
					        CoreSitePluginsAssignSubmissionComponent,
 | 
				
			||||||
 | 
					        // @todo CoreSitePluginsWorkshopAssessmentStrategyComponent,
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CoreSitePluginsComponentsModule {}
 | 
				
			||||||
@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					<core-site-plugins-plugin-content *ngIf="component && method" [component]="component" [method]="method" [args]="args"
 | 
				
			||||||
 | 
					    [initResult]="initResult" [data]="data">
 | 
				
			||||||
 | 
					</core-site-plugins-plugin-content>
 | 
				
			||||||
@ -0,0 +1,104 @@
 | 
				
			|||||||
 | 
					// (C) Copyright 2015 Moodle Pty Ltd.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Component, OnChanges, Input, ViewChild, Output, EventEmitter } from '@angular/core';
 | 
				
			||||||
 | 
					import { IonRefresher } from '@ionic/angular';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { CoreCourseFormatComponent } from '@features/course/components/format/format';
 | 
				
			||||||
 | 
					import { CoreCourseModuleCompletionData, CoreCourseSectionWithStatus } from '@features/course/services/course-helper';
 | 
				
			||||||
 | 
					import { CoreCourseFormatDelegate } from '@features/course/services/format-delegate';
 | 
				
			||||||
 | 
					import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
 | 
				
			||||||
 | 
					import { CoreSitePlugins, CoreSitePluginsContent } from '@features/siteplugins/services/siteplugins';
 | 
				
			||||||
 | 
					import { CoreSitePluginsPluginContentComponent } from '../plugin-content/plugin-content';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component that displays the index of a course format site plugin.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'core-site-plugins-course-format',
 | 
				
			||||||
 | 
					    templateUrl: 'core-siteplugins-course-format.html',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CoreSitePluginsCourseFormatComponent implements OnChanges {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Input() course?: CoreCourseAnyCourseData; // The course to render.
 | 
				
			||||||
 | 
					    @Input() sections?: CoreCourseSectionWithStatus[]; // List of course sections. The status will be calculated in this component.
 | 
				
			||||||
 | 
					    @Input() downloadEnabled?: boolean; // Whether the download of sections and modules is enabled.
 | 
				
			||||||
 | 
					    @Input() initialSectionId?: number; // The section to load first (by ID).
 | 
				
			||||||
 | 
					    @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.
 | 
				
			||||||
 | 
					    @Output() completionChanged = new EventEmitter<CoreCourseModuleCompletionData>(); // Notify when any module completion changes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Special input, allows access to the parent instance properties and methods.
 | 
				
			||||||
 | 
					    // Please notice that all the other inputs/outputs are also accessible through this instance, so they could be removed.
 | 
				
			||||||
 | 
					    // However, we decided to keep them to support ngOnChanges and to make templates easier to read.
 | 
				
			||||||
 | 
					    @Input() coreCourseFormatComponent?: CoreCourseFormatComponent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @ViewChild(CoreSitePluginsPluginContentComponent) content?: CoreSitePluginsPluginContentComponent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    component?: string;
 | 
				
			||||||
 | 
					    method?: string;
 | 
				
			||||||
 | 
					    args?: Record<string, unknown>;
 | 
				
			||||||
 | 
					    initResult?: CoreSitePluginsContent | null;
 | 
				
			||||||
 | 
					    data?: Record<string, unknown>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Detect changes on input properties.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnChanges(): void {
 | 
				
			||||||
 | 
					        if (!this.course || !this.course.format) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!this.component) {
 | 
				
			||||||
 | 
					            // Initialize the data.
 | 
				
			||||||
 | 
					            const handlerName = CoreCourseFormatDelegate.getHandlerName(this.course.format);
 | 
				
			||||||
 | 
					            const handler = CoreSitePlugins.getSitePluginHandler(handlerName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (handler) {
 | 
				
			||||||
 | 
					                this.component = handler.plugin.component;
 | 
				
			||||||
 | 
					                this.method = handler.handlerSchema.method;
 | 
				
			||||||
 | 
					                this.args = {
 | 
				
			||||||
 | 
					                    courseid: this.course.id,
 | 
				
			||||||
 | 
					                    downloadenabled: this.downloadEnabled,
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                this.initResult = handler.initResult;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Pass input data to the component.
 | 
				
			||||||
 | 
					        this.data = {
 | 
				
			||||||
 | 
					            course: this.course,
 | 
				
			||||||
 | 
					            sections: this.sections,
 | 
				
			||||||
 | 
					            downloadEnabled: this.downloadEnabled,
 | 
				
			||||||
 | 
					            initialSectionId: this.initialSectionId,
 | 
				
			||||||
 | 
					            initialSectionNumber: this.initialSectionNumber,
 | 
				
			||||||
 | 
					            moduleId: this.moduleId,
 | 
				
			||||||
 | 
					            completionChanged: this.completionChanged,
 | 
				
			||||||
 | 
					            coreCourseFormatComponent: this.coreCourseFormatComponent,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Refresh the data.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param refresher Refresher.
 | 
				
			||||||
 | 
					     * @param done Function to call when done.
 | 
				
			||||||
 | 
					     * @param afterCompletionChange Whether the refresh is due to a completion change.
 | 
				
			||||||
 | 
					     * @return Promise resolved when done.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    async doRefresh(refresher?: CustomEvent<IonRefresher>, done?: () => void, afterCompletionChange?: boolean): Promise<void> {
 | 
				
			||||||
 | 
					        await this.content?.refreshContent(afterCompletionChange);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					<ion-content>
 | 
				
			||||||
 | 
					    <ion-refresher [disabled]="!ptrEnabled || !content || !content.dataLoaded" (ionRefresh)="refreshData($event.target)">
 | 
				
			||||||
 | 
					        <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
 | 
				
			||||||
 | 
					    </ion-refresher>
 | 
				
			||||||
 | 
					    <core-site-plugins-plugin-content *ngIf="component && method" [component]="component" [method]="method" [args]="args"
 | 
				
			||||||
 | 
					        [initResult]="initResult">
 | 
				
			||||||
 | 
					    </core-site-plugins-plugin-content>
 | 
				
			||||||
 | 
					</ion-content>
 | 
				
			||||||
@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					// (C) Copyright 2015 Moodle Pty Ltd.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Component, OnInit, Input, ViewChild } from '@angular/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { CoreSitePlugins, CoreSitePluginsContent } from '@features/siteplugins/services/siteplugins';
 | 
				
			||||||
 | 
					import { IonRefresher } from '@ionic/angular';
 | 
				
			||||||
 | 
					import { CoreUtils } from '@services/utils/utils';
 | 
				
			||||||
 | 
					import { CoreSitePluginsPluginContentComponent } from '../plugin-content/plugin-content';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component that displays the index of a course option site plugin.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'core-site-plugins-course-option',
 | 
				
			||||||
 | 
					    templateUrl: 'core-siteplugins-course-option.html',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CoreSitePluginsCourseOptionComponent implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Input() courseId?: number;
 | 
				
			||||||
 | 
					    @Input() handlerUniqueName?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @ViewChild(CoreSitePluginsPluginContentComponent) content?: CoreSitePluginsPluginContentComponent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    component?: string;
 | 
				
			||||||
 | 
					    method?: string;
 | 
				
			||||||
 | 
					    args?: Record<string, unknown>;
 | 
				
			||||||
 | 
					    initResult?: CoreSitePluginsContent | null;
 | 
				
			||||||
 | 
					    ptrEnabled = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Component being initialized.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnInit(): void {
 | 
				
			||||||
 | 
					        if (!this.handlerUniqueName) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const handler = CoreSitePlugins.getSitePluginHandler(this.handlerUniqueName);
 | 
				
			||||||
 | 
					        if (!handler) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.component = handler.plugin.component;
 | 
				
			||||||
 | 
					        this.method = handler.handlerSchema.method;
 | 
				
			||||||
 | 
					        this.args = {
 | 
				
			||||||
 | 
					            courseid: this.courseId,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        this.initResult = handler.initResult;
 | 
				
			||||||
 | 
					        this.ptrEnabled = !('ptrenabled' in handler.handlerSchema) ||
 | 
				
			||||||
 | 
					            !CoreUtils.isFalseOrZero(handler.handlerSchema.ptrenabled);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Refresh the data.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param refresher Refresher.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    async refreshData(refresher: IonRefresher): Promise<void> {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            await this.content?.refreshContent(false);
 | 
				
			||||||
 | 
					        } finally {
 | 
				
			||||||
 | 
					            refresher.complete();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					<!-- Buttons to add to the header. -->
 | 
				
			||||||
 | 
					<core-navbar-buttons slot="end">
 | 
				
			||||||
 | 
					    <core-context-menu>
 | 
				
			||||||
 | 
					        <core-context-menu-item [hidden]="!displayOpenInBrowser || !externalUrl || (
 | 
				
			||||||
 | 
					            content?.compileComponent?.componentInstance?.displayOpenInBrowser === false)" [priority]="900"
 | 
				
			||||||
 | 
					            [content]="'core.openinbrowser' | translate" [href]="externalUrl" iconAction="fas-external-link-alt">
 | 
				
			||||||
 | 
					        </core-context-menu-item>
 | 
				
			||||||
 | 
					        <core-context-menu-item [hidden]="!displayDescription || !description || (
 | 
				
			||||||
 | 
					            content?.compileComponent?.componentInstance?.displayDescription === false)" [priority]="800"
 | 
				
			||||||
 | 
					            [content]="'core.moduleintro' | translate" (action)="expandDescription()" iconAction="fas-arrow-right">
 | 
				
			||||||
 | 
					        </core-context-menu-item>
 | 
				
			||||||
 | 
					        <core-context-menu-item [hidden]="!displayRefresh || (
 | 
				
			||||||
 | 
					            content?.compileComponent?.componentInstance?.displayRefresh === false)" [priority]="700"
 | 
				
			||||||
 | 
					            [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon"
 | 
				
			||||||
 | 
					            [closeOnClick]="false">
 | 
				
			||||||
 | 
					        </core-context-menu-item>
 | 
				
			||||||
 | 
					        <core-context-menu-item [hidden]="!displayPrefetch || !prefetchStatusIcon || (
 | 
				
			||||||
 | 
					            content?.compileComponent?.componentInstance?.displayPrefetch === false)" [priority]="600" [content]="prefetchText"
 | 
				
			||||||
 | 
					            (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false">
 | 
				
			||||||
 | 
					        </core-context-menu-item>
 | 
				
			||||||
 | 
					        <core-context-menu-item [hidden]="!displaySize || !size || (
 | 
				
			||||||
 | 
					            content?.compileComponent?.componentInstance?.displaySize === false)" [priority]="500"
 | 
				
			||||||
 | 
					            [content]="'core.clearstoreddata' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()"
 | 
				
			||||||
 | 
					            iconAction="fas-trash" [closeOnClick]="false">
 | 
				
			||||||
 | 
					        </core-context-menu-item>
 | 
				
			||||||
 | 
					    </core-context-menu>
 | 
				
			||||||
 | 
					</core-navbar-buttons>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<core-site-plugins-plugin-content *ngIf="component && method" [component]="component" [method]="method" [args]="args"
 | 
				
			||||||
 | 
					    [initResult]="initResult" [data]="jsData" [pageTitle]="pageTitle" [preSets]="preSets" (onContentLoaded)="contentLoaded($event)"
 | 
				
			||||||
 | 
					    (onLoadingContent)="contentLoading()">
 | 
				
			||||||
 | 
					</core-site-plugins-plugin-content>
 | 
				
			||||||
@ -0,0 +1,205 @@
 | 
				
			|||||||
 | 
					// (C) Copyright 2015 Moodle Pty Ltd.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { CoreConstants } from '@/core/constants';
 | 
				
			||||||
 | 
					import { Component, OnInit, OnDestroy, Input, ViewChild } from '@angular/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { CoreSiteWSPreSets } from '@classes/site';
 | 
				
			||||||
 | 
					import { CoreCourseHelper, CoreCourseModule } from '@features/course/services/course-helper';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					    CoreCourseModuleDelegate,
 | 
				
			||||||
 | 
					    CoreCourseModuleMainComponent,
 | 
				
			||||||
 | 
					} from '@features/course/services/module-delegate';
 | 
				
			||||||
 | 
					import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					    CoreSitePlugins,
 | 
				
			||||||
 | 
					    CoreSitePluginsContent,
 | 
				
			||||||
 | 
					    CoreSitePluginsCourseModuleHandlerData,
 | 
				
			||||||
 | 
					} from '@features/siteplugins/services/siteplugins';
 | 
				
			||||||
 | 
					import { IonRefresher } from '@ionic/angular';
 | 
				
			||||||
 | 
					import { CoreTextUtils } from '@services/utils/text';
 | 
				
			||||||
 | 
					import { CoreUtils } from '@services/utils/utils';
 | 
				
			||||||
 | 
					import { Translate } from '@singletons';
 | 
				
			||||||
 | 
					import { CoreEventObserver } from '@singletons/events';
 | 
				
			||||||
 | 
					import { CoreSitePluginsPluginContentComponent } from '../plugin-content/plugin-content';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component that displays the index of a module site plugin.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'core-site-plugins-module-index',
 | 
				
			||||||
 | 
					    templateUrl: 'core-siteplugins-module-index.html',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CoreSitePluginsModuleIndexComponent implements OnInit, OnDestroy, CoreCourseModuleMainComponent {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Input() module!: CoreCourseModule; // The module.
 | 
				
			||||||
 | 
					    @Input() courseId!: number; // Course ID the module belongs to.
 | 
				
			||||||
 | 
					    @Input() pageTitle?: string; // Current page title. It can be used by the "new-content" directives.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @ViewChild(CoreSitePluginsPluginContentComponent) content?: CoreSitePluginsPluginContentComponent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    component?: string;
 | 
				
			||||||
 | 
					    method?: string;
 | 
				
			||||||
 | 
					    args?: Record<string, unknown>;
 | 
				
			||||||
 | 
					    initResult?: CoreSitePluginsContent | null;
 | 
				
			||||||
 | 
					    preSets?: CoreSiteWSPreSets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Data for context menu.
 | 
				
			||||||
 | 
					    externalUrl?: string;
 | 
				
			||||||
 | 
					    description?: string;
 | 
				
			||||||
 | 
					    refreshIcon?: string;
 | 
				
			||||||
 | 
					    prefetchStatus?: string;
 | 
				
			||||||
 | 
					    prefetchStatusIcon?: string;
 | 
				
			||||||
 | 
					    prefetchText?: string;
 | 
				
			||||||
 | 
					    size?: string;
 | 
				
			||||||
 | 
					    contextMenuStatusObserver?: CoreEventObserver;
 | 
				
			||||||
 | 
					    contextFileStatusObserver?: CoreEventObserver;
 | 
				
			||||||
 | 
					    displayOpenInBrowser = true;
 | 
				
			||||||
 | 
					    displayDescription = true;
 | 
				
			||||||
 | 
					    displayRefresh = true;
 | 
				
			||||||
 | 
					    displayPrefetch = true;
 | 
				
			||||||
 | 
					    displaySize = true;
 | 
				
			||||||
 | 
					    ptrEnabled = true;
 | 
				
			||||||
 | 
					    isDestroyed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    jsData?: Record<string, unknown>; // Data to pass to the component.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Component being initialized.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnInit(): void {
 | 
				
			||||||
 | 
					        this.refreshIcon = 'spinner';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!this.module) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const handlerName = CoreCourseModuleDelegate.getHandlerName(this.module.modname);
 | 
				
			||||||
 | 
					        const handler = CoreSitePlugins.getSitePluginHandler(handlerName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (handler) {
 | 
				
			||||||
 | 
					            this.component = handler.plugin.component;
 | 
				
			||||||
 | 
					            this.preSets = { componentId: this.module.id };
 | 
				
			||||||
 | 
					            this.method = handler.handlerSchema.method;
 | 
				
			||||||
 | 
					            this.args = {
 | 
				
			||||||
 | 
					                courseid: this.courseId,
 | 
				
			||||||
 | 
					                cmid: this.module.id,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            this.initResult = handler.initResult;
 | 
				
			||||||
 | 
					            this.jsData = {
 | 
				
			||||||
 | 
					                module: this.module,
 | 
				
			||||||
 | 
					                courseId: this.courseId,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const handlerSchema = <CoreSitePluginsCourseModuleHandlerData> handler.handlerSchema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.displayOpenInBrowser = !CoreUtils.isFalseOrZero(handlerSchema.displayopeninbrowser);
 | 
				
			||||||
 | 
					            this.displayDescription = !CoreUtils.isFalseOrZero(handlerSchema.displaydescription);
 | 
				
			||||||
 | 
					            this.displayRefresh = !CoreUtils.isFalseOrZero(handlerSchema.displayrefresh);
 | 
				
			||||||
 | 
					            this.displayPrefetch = !CoreUtils.isFalseOrZero(handlerSchema.displayprefetch);
 | 
				
			||||||
 | 
					            this.displaySize = !CoreUtils.isFalseOrZero(handlerSchema.displaysize);
 | 
				
			||||||
 | 
					            this.ptrEnabled = !CoreUtils.isFalseOrZero(handlerSchema.ptrenabled);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Get the data for the context menu.
 | 
				
			||||||
 | 
					        this.description = this.module.description;
 | 
				
			||||||
 | 
					        this.externalUrl = this.module.url;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Refresh the data.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param refresher Refresher.
 | 
				
			||||||
 | 
					     * @param done Function to call when done.
 | 
				
			||||||
 | 
					     * @return Promise resolved when done.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    async doRefresh(refresher?: CustomEvent<IonRefresher> | null, done?: () => void): Promise<void> {
 | 
				
			||||||
 | 
					        if (this.content) {
 | 
				
			||||||
 | 
					            this.refreshIcon = CoreConstants.ICON_LOADING;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            await this.content?.refreshContent(false);
 | 
				
			||||||
 | 
					        } finally {
 | 
				
			||||||
 | 
					            refresher?.detail.complete();
 | 
				
			||||||
 | 
					            done && done();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Function called when the data of the site plugin content is loaded.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    contentLoaded(refresh: boolean): void {
 | 
				
			||||||
 | 
					        this.refreshIcon = CoreConstants.ICON_REFRESH;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Check if there is a prefetch handler for this type of module.
 | 
				
			||||||
 | 
					        if (CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(this.module)) {
 | 
				
			||||||
 | 
					            CoreCourseHelper.fillContextMenu(this, this.module, this.courseId, refresh, this.component);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Function called when starting to load the data of the site plugin content.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    contentLoading(): void {
 | 
				
			||||||
 | 
					        this.refreshIcon = CoreConstants.ICON_LOADING;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Expand the description.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    expandDescription(): void {
 | 
				
			||||||
 | 
					        CoreTextUtils.viewText(Translate.instant('core.description'), this.description!, {
 | 
				
			||||||
 | 
					            component: this.component,
 | 
				
			||||||
 | 
					            componentId: this.module.id,
 | 
				
			||||||
 | 
					            filter: true,
 | 
				
			||||||
 | 
					            contextLevel: 'module',
 | 
				
			||||||
 | 
					            instanceId: this.module.id,
 | 
				
			||||||
 | 
					            courseId: this.courseId,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Prefetch the module.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    prefetch(): void {
 | 
				
			||||||
 | 
					        CoreCourseHelper.contextMenuPrefetch(this, this.module, this.courseId);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Confirm and remove downloaded files.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    removeFiles(): void {
 | 
				
			||||||
 | 
					        CoreCourseHelper.confirmAndRemoveFiles(this.module, this.courseId);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Component destroyed.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnDestroy(): void {
 | 
				
			||||||
 | 
					        this.isDestroyed = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Call a certain function on the component instance.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @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.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    callComponentFunction(name: string, params?: unknown[]): unknown | undefined {
 | 
				
			||||||
 | 
					        return this.content?.callComponentFunction(name, params);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<ion-item-divider class="ion-text-wrap" detail="true" (click)="gotoBlock()">
 | 
				
			||||||
 | 
					    <ion-label>
 | 
				
			||||||
 | 
					        <h2>{{ title | translate }}</h2>
 | 
				
			||||||
 | 
					    </ion-label>
 | 
				
			||||||
 | 
					</ion-item-divider>
 | 
				
			||||||
@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					// (C) Copyright 2015 Moodle Pty Ltd.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { OnInit, Component } from '@angular/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
 | 
				
			||||||
 | 
					import { CoreBlockDelegate } from '@features/block/services/block-delegate';
 | 
				
			||||||
 | 
					import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component to render blocks with only a title and link.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'core-siteplugins-only-title-block',
 | 
				
			||||||
 | 
					    templateUrl: 'core-siteplugins-only-title-block.html',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CoreSitePluginsOnlyTitleBlockComponent  extends CoreBlockBaseComponent implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor() {
 | 
				
			||||||
 | 
					        super('CoreSitePluginsOnlyTitleBlockComponent');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Component being initialized.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    async ngOnInit(): Promise<void> {
 | 
				
			||||||
 | 
					        super.ngOnInit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.fetchContentDefaultError = 'Error getting ' + (this.block.contents?.title || 'block') + ' data.';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Go to the block page.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    gotoBlock(): void {
 | 
				
			||||||
 | 
					        const handlerName = CoreBlockDelegate.getHandlerName(this.block.name);
 | 
				
			||||||
 | 
					        const handler = CoreSitePlugins.getSitePluginHandler(handlerName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!handler) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // @todo
 | 
				
			||||||
 | 
					        // navCtrl.push('CoreSitePluginsPluginPage', {
 | 
				
			||||||
 | 
					        //     title: this.title,
 | 
				
			||||||
 | 
					        //     component: handler.plugin.component,
 | 
				
			||||||
 | 
					        //     method: handler.handlerSchema.method,
 | 
				
			||||||
 | 
					        //     initResult: handler.initResult,
 | 
				
			||||||
 | 
					        //     args: {
 | 
				
			||||||
 | 
					        //         contextlevel: this.contextLevel,
 | 
				
			||||||
 | 
					        //         instanceid: this.instanceId,
 | 
				
			||||||
 | 
					        //     },
 | 
				
			||||||
 | 
					        //     ptrEnabled: handler.handlerSchema.ptrenabled,
 | 
				
			||||||
 | 
					        // });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					<core-loading [hideUntil]="dataLoaded" class="core-loading-center">
 | 
				
			||||||
 | 
					    <core-compile-html [text]="content" [javascript]="javascript" [jsData]="jsData" [forceCompile]="forceCompile" #compile>
 | 
				
			||||||
 | 
					    </core-compile-html>
 | 
				
			||||||
 | 
					</core-loading>
 | 
				
			||||||
@ -0,0 +1,219 @@
 | 
				
			|||||||
 | 
					// (C) Copyright 2015 Moodle Pty Ltd.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Component, OnInit, Input, Output, EventEmitter, DoCheck, KeyValueDiffers, ViewChild, KeyValueDiffer } from '@angular/core';
 | 
				
			||||||
 | 
					import { CoreSiteWSPreSets } from '@classes/site';
 | 
				
			||||||
 | 
					import { CoreCompileHtmlComponent } from '@features/compile/components/compile-html/compile-html';
 | 
				
			||||||
 | 
					import { CoreSitePlugins, CoreSitePluginsContent } from '@features/siteplugins/services/siteplugins';
 | 
				
			||||||
 | 
					import { CoreDomUtils } from '@services/utils/dom';
 | 
				
			||||||
 | 
					import { Subject } from 'rxjs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component to render a site plugin content.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'core-site-plugins-plugin-content',
 | 
				
			||||||
 | 
					    templateUrl: 'core-siteplugins-plugin-content.html',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CoreSitePluginsPluginContentComponent implements OnInit, DoCheck {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get the compile element. Don't set the right type to prevent circular dependencies.
 | 
				
			||||||
 | 
					    @ViewChild('compile') compileComponent?: CoreCompileHtmlComponent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Input() component!: string;
 | 
				
			||||||
 | 
					    @Input() method!: string;
 | 
				
			||||||
 | 
					    @Input() args?: Record<string, unknown>;
 | 
				
			||||||
 | 
					    @Input() initResult?: CoreSitePluginsContent | null; // Result of the init WS call of the handler.
 | 
				
			||||||
 | 
					    @Input() data?: Record<string, unknown>; // Data to pass to the component.
 | 
				
			||||||
 | 
					    @Input() preSets?: CoreSiteWSPreSets; // The preSets for the WS call.
 | 
				
			||||||
 | 
					    @Input() pageTitle?: string; // Current page title. It can be used by the "new-content" directives.
 | 
				
			||||||
 | 
					    @Output() onContentLoaded = new EventEmitter<boolean>(); // Emits an event when the content is loaded.
 | 
				
			||||||
 | 
					    @Output() onLoadingContent = new EventEmitter<boolean>(); // Emits an event when starts to load the content.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    content?: string; // Content.
 | 
				
			||||||
 | 
					    javascript?: string; // Javascript to execute.
 | 
				
			||||||
 | 
					    otherData?: Record<string, unknown>; // Other data of the content.
 | 
				
			||||||
 | 
					    dataLoaded = false;
 | 
				
			||||||
 | 
					    invalidateObservable = new Subject<void>(); // An observable to notify observers when to invalidate data.
 | 
				
			||||||
 | 
					    jsData?: Record<string, unknown>; // Data to pass to the component.
 | 
				
			||||||
 | 
					    forceCompile?: boolean; // Force compilation on PTR.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected differ: KeyValueDiffer<unknown, unknown>; // To detect changes in the data input.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor(differs: KeyValueDiffers) {
 | 
				
			||||||
 | 
					        this.differ = differs.find([]).create();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Component being initialized.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnInit(): void {
 | 
				
			||||||
 | 
					        this.fetchContent();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Detect and act upon changes that Angular can’t or won’t detect on its own (objects and arrays).
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngDoCheck(): void {
 | 
				
			||||||
 | 
					        if (!this.data || !this.jsData) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Check if there's any change in the data object.
 | 
				
			||||||
 | 
					        const changes = this.differ.diff(this.data);
 | 
				
			||||||
 | 
					        if (changes) {
 | 
				
			||||||
 | 
					            this.jsData = Object.assign(this.jsData, this.data);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Fetches the content to render.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param refresh Whether the user is refreshing.
 | 
				
			||||||
 | 
					     * @return Promise resolved when done.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    async fetchContent(refresh?: boolean): Promise<void> {
 | 
				
			||||||
 | 
					        this.onLoadingContent.emit(refresh);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.forceCompile = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const preSets = Object.assign({}, this.preSets);
 | 
				
			||||||
 | 
					        preSets.component = preSets.component || this.component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            const result = await CoreSitePlugins.getContent(this.component, this.method, this.args, preSets);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.content = result.templates.length ? result.templates[0].html : ''; // Load first template.
 | 
				
			||||||
 | 
					            this.javascript = result.javascript;
 | 
				
			||||||
 | 
					            this.otherData = result.otherdata;
 | 
				
			||||||
 | 
					            this.data = this.data || {};
 | 
				
			||||||
 | 
					            this.forceCompile = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.jsData = Object.assign(this.data, CoreSitePlugins.createDataForJS(this.initResult, result));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Pass some methods as jsData so they can be called from the template too.
 | 
				
			||||||
 | 
					            this.jsData.fetchContent = this.fetchContent.bind(this);
 | 
				
			||||||
 | 
					            this.jsData.openContent = this.openContent.bind(this);
 | 
				
			||||||
 | 
					            this.jsData.refreshContent = this.refreshContent.bind(this);
 | 
				
			||||||
 | 
					            this.jsData.updateContent = this.updateContent.bind(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.onContentLoaded.emit(refresh);
 | 
				
			||||||
 | 
					        } catch (error) {
 | 
				
			||||||
 | 
					            // Make it think it's loaded - otherwise it sticks on 'loading' and stops navigation working.
 | 
				
			||||||
 | 
					            this.content = '<div></div>';
 | 
				
			||||||
 | 
					            this.onContentLoaded.emit(refresh);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            CoreDomUtils.showErrorModalDefault(error, 'core.errorloadingcontent', true);
 | 
				
			||||||
 | 
					        } finally {
 | 
				
			||||||
 | 
					            this.dataLoaded = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Open a new page with a new content.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param title The title to display with the new content.
 | 
				
			||||||
 | 
					     * @param args New params.
 | 
				
			||||||
 | 
					     * @param component New component. If not provided, current component
 | 
				
			||||||
 | 
					     * @param method New method. If not provided, current method
 | 
				
			||||||
 | 
					     * @param jsData JS variables to pass to the new view so they can be used in the template or JS.
 | 
				
			||||||
 | 
					     *               If true is supplied instead of an object, all initial variables from current page will be copied.
 | 
				
			||||||
 | 
					     * @param preSets The preSets for the WS call of the new content.
 | 
				
			||||||
 | 
					     * @param ptrEnabled Whether PTR should be enabled in the new page. Defaults to true.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    openContent(
 | 
				
			||||||
 | 
					        title: string,
 | 
				
			||||||
 | 
					        args?: Record<string, unknown>,
 | 
				
			||||||
 | 
					        component?: string,
 | 
				
			||||||
 | 
					        method?: string,
 | 
				
			||||||
 | 
					        jsData?: Record<string, unknown> | boolean,
 | 
				
			||||||
 | 
					        preSets?: CoreSiteWSPreSets,
 | 
				
			||||||
 | 
					        ptrEnabled?: boolean,
 | 
				
			||||||
 | 
					    ): void {
 | 
				
			||||||
 | 
					        if (jsData === true) {
 | 
				
			||||||
 | 
					            jsData = this.data;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // @todo
 | 
				
			||||||
 | 
					        // this.navCtrl.push('CoreSitePluginsPluginPage', {
 | 
				
			||||||
 | 
					        //     title: title,
 | 
				
			||||||
 | 
					        //     component: component || this.component,
 | 
				
			||||||
 | 
					        //     method: method || this.method,
 | 
				
			||||||
 | 
					        //     args: args,
 | 
				
			||||||
 | 
					        //     initResult: this.initResult,
 | 
				
			||||||
 | 
					        //     jsData: jsData,
 | 
				
			||||||
 | 
					        //     preSets: preSets,
 | 
				
			||||||
 | 
					        //     ptrEnabled: ptrEnabled,
 | 
				
			||||||
 | 
					        // });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Refresh the data.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param showSpinner Whether to show spinner while refreshing.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    async refreshContent(showSpinner: boolean = true): Promise<void> {
 | 
				
			||||||
 | 
					        if (showSpinner) {
 | 
				
			||||||
 | 
					            this.dataLoaded = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.invalidateObservable.next(); // Notify observers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            await CoreSitePlugins.invalidateContent(this.component, this.method, this.args);
 | 
				
			||||||
 | 
					        } finally {
 | 
				
			||||||
 | 
					            await this.fetchContent(true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Update the content, usually with a different method or params.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param args New params.
 | 
				
			||||||
 | 
					     * @param component New component. If not provided, current component
 | 
				
			||||||
 | 
					     * @param method New method. If not provided, current method
 | 
				
			||||||
 | 
					     * @param jsData JS variables to pass to the new view so they can be used in the template or JS.
 | 
				
			||||||
 | 
					     * @param preSets New preSets to use. If not provided, use current preSets.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    updateContent(
 | 
				
			||||||
 | 
					        args?: Record<string, unknown>,
 | 
				
			||||||
 | 
					        component?: string,
 | 
				
			||||||
 | 
					        method?: string,
 | 
				
			||||||
 | 
					        jsData?: Record<string, unknown>,
 | 
				
			||||||
 | 
					        preSets?: CoreSiteWSPreSets,
 | 
				
			||||||
 | 
					    ): void {
 | 
				
			||||||
 | 
					        this.component = component || this.component;
 | 
				
			||||||
 | 
					        this.method = method || this.method;
 | 
				
			||||||
 | 
					        this.args = args;
 | 
				
			||||||
 | 
					        this.dataLoaded = false;
 | 
				
			||||||
 | 
					        this.preSets = preSets || this.preSets;
 | 
				
			||||||
 | 
					        if (jsData) {
 | 
				
			||||||
 | 
					            Object.assign(this.data, jsData);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.fetchContent();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Call a certain function on the component instance.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @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.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    callComponentFunction(name: string, params?: unknown[]): unknown | undefined {
 | 
				
			||||||
 | 
					        return this.compileComponent?.callComponentFunction(name, params);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>
 | 
				
			||||||
@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					// (C) Copyright 2015 Moodle Pty Ltd.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { CoreQuestionBehaviourDelegate } from '@features/question/services/behaviour-delegate';
 | 
				
			||||||
 | 
					import { CoreQuestionBehaviourButton, CoreQuestionQuestion } from '@features/question/services/question-helper';
 | 
				
			||||||
 | 
					import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/classes/compile-init-component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component that displays a question behaviour created using a site plugin.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'core-site-plugins-question-behaviour',
 | 
				
			||||||
 | 
					    templateUrl: 'core-siteplugins-question-behaviour.html',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CoreSitePluginsQuestionBehaviourComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Input() question?: CoreQuestionQuestion; // The question.
 | 
				
			||||||
 | 
					    @Input() component?: string; // The component the question belongs to.
 | 
				
			||||||
 | 
					    @Input() componentId?: number; // ID of the component the question belongs to.
 | 
				
			||||||
 | 
					    @Input() attemptId?: number; // Attempt ID.
 | 
				
			||||||
 | 
					    @Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
 | 
				
			||||||
 | 
					    @Input() contextLevel?: string; // The context level.
 | 
				
			||||||
 | 
					    @Input() contextInstanceId?: number; // The instance ID related to the context.
 | 
				
			||||||
 | 
					    @Input() courseId?: number; // Course ID the question belongs to (if any). It can be used to improve performance with filters.
 | 
				
			||||||
 | 
					    @Input() review?: boolean; // Whether the user is in review mode.
 | 
				
			||||||
 | 
					    @Input() preferredBehaviour?: string; // Preferred behaviour.
 | 
				
			||||||
 | 
					    @Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
 | 
				
			||||||
 | 
					    @Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor() {
 | 
				
			||||||
 | 
					        super();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Component being initialized.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnInit(): void {
 | 
				
			||||||
 | 
					        // Pass the input and output data to the component.
 | 
				
			||||||
 | 
					        this.jsData.question = this.question;
 | 
				
			||||||
 | 
					        this.jsData.component = this.component;
 | 
				
			||||||
 | 
					        this.jsData.componentId = this.componentId;
 | 
				
			||||||
 | 
					        this.jsData.attemptId = this.attemptId;
 | 
				
			||||||
 | 
					        this.jsData.offlineEnabled = this.offlineEnabled;
 | 
				
			||||||
 | 
					        this.jsData.contextLevel = this.contextLevel;
 | 
				
			||||||
 | 
					        this.jsData.contextInstanceId = this.contextInstanceId;
 | 
				
			||||||
 | 
					        this.jsData.buttonClicked = this.buttonClicked;
 | 
				
			||||||
 | 
					        this.jsData.onAbort = this.onAbort;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (this.question) {
 | 
				
			||||||
 | 
					            this.getHandlerData(CoreQuestionBehaviourDelegate.getHandlerName(this.preferredBehaviour || ''));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>
 | 
				
			||||||
@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					// (C) Copyright 2015 Moodle Pty Ltd.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { AddonModQuizQuestion } from '@features/question/classes/base-question-component';
 | 
				
			||||||
 | 
					import { CoreQuestionDelegate } from '@features/question/services/question-delegate';
 | 
				
			||||||
 | 
					import { CoreQuestionBehaviourButton } from '@features/question/services/question-helper';
 | 
				
			||||||
 | 
					import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/classes/compile-init-component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component that displays a question created using a site plugin.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'core-site-plugins-question',
 | 
				
			||||||
 | 
					    templateUrl: 'core-siteplugins-question.html',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CoreSitePluginsQuestionComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Input() question?: AddonModQuizQuestion; // The question to render.
 | 
				
			||||||
 | 
					    @Input() component?: string; // The component the question belongs to.
 | 
				
			||||||
 | 
					    @Input() componentId?: number; // ID of the component the question belongs to.
 | 
				
			||||||
 | 
					    @Input() attemptId?: number; // Attempt ID.
 | 
				
			||||||
 | 
					    @Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
 | 
				
			||||||
 | 
					    @Input() contextLevel?: string; // The context level.
 | 
				
			||||||
 | 
					    @Input() contextInstanceId?: number; // The instance ID related to the context.
 | 
				
			||||||
 | 
					    @Input() courseId?: number; // Course ID the question belongs to (if any). It can be used to improve performance with filters.
 | 
				
			||||||
 | 
					    @Input() review?: boolean; // Whether the user is in review mode.
 | 
				
			||||||
 | 
					    @Input() preferredBehaviour?: string; // Preferred behaviour.
 | 
				
			||||||
 | 
					    @Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
 | 
				
			||||||
 | 
					    @Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Component being initialized.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnInit(): void {
 | 
				
			||||||
 | 
					        // Pass the input and output data to the component.
 | 
				
			||||||
 | 
					        this.jsData.question = this.question;
 | 
				
			||||||
 | 
					        this.jsData.component = this.component;
 | 
				
			||||||
 | 
					        this.jsData.componentId = this.componentId;
 | 
				
			||||||
 | 
					        this.jsData.attemptId = this.attemptId;
 | 
				
			||||||
 | 
					        this.jsData.offlineEnabled = this.offlineEnabled;
 | 
				
			||||||
 | 
					        this.jsData.contextLevel = this.contextLevel;
 | 
				
			||||||
 | 
					        this.jsData.contextInstanceId = this.contextInstanceId;
 | 
				
			||||||
 | 
					        this.jsData.courseId = this.courseId;
 | 
				
			||||||
 | 
					        this.jsData.review = this.review;
 | 
				
			||||||
 | 
					        this.jsData.preferredBehaviour = this.preferredBehaviour;
 | 
				
			||||||
 | 
					        this.jsData.buttonClicked = this.buttonClicked;
 | 
				
			||||||
 | 
					        this.jsData.onAbort = this.onAbort;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (this.question) {
 | 
				
			||||||
 | 
					            this.getHandlerData(CoreQuestionDelegate.getHandlerName('qtype_' + this.question.type));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>
 | 
				
			||||||
@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					// (C) Copyright 2015 Moodle Pty Ltd.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Component, OnInit, Input } from '@angular/core';
 | 
				
			||||||
 | 
					import { FormGroup } from '@angular/forms';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { AddonModQuizAccessRuleDelegate } from '@addons/mod/quiz/services/access-rules-delegate';
 | 
				
			||||||
 | 
					import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
 | 
				
			||||||
 | 
					import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/classes/compile-init-component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component that displays a quiz access rule created using a site plugin.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'core-site-plugins-quiz-access-rule',
 | 
				
			||||||
 | 
					    templateUrl: 'core-siteplugins-quiz-access-rule.html',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CoreSitePluginsQuizAccessRuleComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Input() rule?: string; // The name of the rule.
 | 
				
			||||||
 | 
					    @Input() quiz?: AddonModQuizQuizWSData; // The quiz the rule belongs to.
 | 
				
			||||||
 | 
					    @Input() attempt?: AddonModQuizAttemptWSData; // The attempt being started/continued.
 | 
				
			||||||
 | 
					    @Input() prefetch?: boolean; // Whether the user is prefetching the quiz.
 | 
				
			||||||
 | 
					    @Input() siteId?: string; // Site ID.
 | 
				
			||||||
 | 
					    @Input() form?: FormGroup; // Form where to add the form control.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Component being initialized.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnInit(): void {
 | 
				
			||||||
 | 
					        // Pass the input and output data to the component.
 | 
				
			||||||
 | 
					        this.jsData.rule = this.rule;
 | 
				
			||||||
 | 
					        this.jsData.quiz = this.quiz;
 | 
				
			||||||
 | 
					        this.jsData.attempt = this.attempt;
 | 
				
			||||||
 | 
					        this.jsData.prefetch = this.prefetch;
 | 
				
			||||||
 | 
					        this.jsData.siteId = this.siteId;
 | 
				
			||||||
 | 
					        this.jsData.form = this.form;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (this.rule) {
 | 
				
			||||||
 | 
					            this.getHandlerData(AddonModQuizAccessRuleDelegate.getHandlerName(this.rule));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>
 | 
				
			||||||
@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					// (C) Copyright 2015 Moodle Pty Ltd.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Component, OnInit, Input } from '@angular/core';
 | 
				
			||||||
 | 
					import { FormGroup } from '@angular/forms';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { AuthEmailSignupProfileField } from '@features/login/services/login-helper';
 | 
				
			||||||
 | 
					import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/classes/compile-init-component';
 | 
				
			||||||
 | 
					import { CoreUserProfileField } from '@features/user/services/user';
 | 
				
			||||||
 | 
					import { CoreUserProfileFieldDelegate } from '@features/user/services/user-profile-field-delegate';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component that displays a user profile field created using a site plugin.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'core-site-plugins-user-profile-field',
 | 
				
			||||||
 | 
					    templateUrl: 'core-siteplugins-user-profile-field.html',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class CoreSitePluginsUserProfileFieldComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
 | 
				
			||||||
 | 
					    @Input() signup = false; // True if editing the field in signup. Defaults to false.
 | 
				
			||||||
 | 
					    @Input() edit = false; // True if editing the field. Defaults to false.
 | 
				
			||||||
 | 
					    @Input() disabled = false; // True if disabled. Defaults to false.
 | 
				
			||||||
 | 
					    @Input() form?: FormGroup; // Form where to add the form control. Required if edit=true or signup=true.
 | 
				
			||||||
 | 
					    @Input() registerAuth?: string; // Register auth method. E.g. 'email'.
 | 
				
			||||||
 | 
					    @Input() contextLevel?: string; // The context level.
 | 
				
			||||||
 | 
					    @Input() contextInstanceId?: number; // The instance ID related to the context.
 | 
				
			||||||
 | 
					    @Input() courseId?: number; // Course ID the field belongs to (if any). It can be used to improve performance with filters.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Component being initialized.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnInit(): void {
 | 
				
			||||||
 | 
					        // Pass the input data to the component.
 | 
				
			||||||
 | 
					        this.jsData.field = this.field;
 | 
				
			||||||
 | 
					        this.jsData.signup = this.signup;
 | 
				
			||||||
 | 
					        this.jsData.edit = this.edit;
 | 
				
			||||||
 | 
					        this.jsData.disabled = this.disabled;
 | 
				
			||||||
 | 
					        this.jsData.form = this.form;
 | 
				
			||||||
 | 
					        this.jsData.registerAuth = this.registerAuth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (this.field) {
 | 
				
			||||||
 | 
					            const type = 'type' in this.field ? this.field.type : this.field.datatype;
 | 
				
			||||||
 | 
					            this.getHandlerData(CoreUserProfileFieldDelegate.getHandlerName(type || ''));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -27,12 +27,15 @@ import { CoreUserProfileField } from '@features/user/services/user';
 | 
				
			|||||||
export abstract class CoreUserProfileFieldBaseComponent implements OnInit {
 | 
					export abstract class CoreUserProfileFieldBaseComponent implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
 | 
					    @Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
 | 
				
			||||||
 | 
					    @Input() signup = false; // True if editing the field in signup. Defaults to false.
 | 
				
			||||||
    @Input() edit = false; // True if editing the field. Defaults to false.
 | 
					    @Input() edit = false; // True if editing the field. Defaults to false.
 | 
				
			||||||
    @Input() disabled = false; // True if disabled. Defaults to false.
 | 
					    @Input() disabled = false; // True if disabled. Defaults to false.
 | 
				
			||||||
    @Input() form?: FormGroup; // Form where to add the form control.
 | 
					    @Input() form?: FormGroup; // Form where to add the form control. Required if edit=true or signup=true.
 | 
				
			||||||
 | 
					    @Input() registerAuth?: string; // Register auth method. E.g. 'email'.
 | 
				
			||||||
    @Input() contextLevel?: string; // The context level.
 | 
					    @Input() contextLevel?: string; // The context level.
 | 
				
			||||||
    @Input() contextInstanceId?: number; // The instance ID related to the context.
 | 
					    @Input() contextInstanceId?: number; // The instance ID related to the context.
 | 
				
			||||||
    @Input() courseId?: number; // The course the field belongs to (if any).
 | 
					    @Input() courseId?: number; // Course ID the field belongs to (if any). It can be used to improve performance with filters.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    control?: FormControl;
 | 
					    control?: FormControl;
 | 
				
			||||||
    modelName = '';
 | 
					    modelName = '';
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,7 @@ import { Component, Input, OnInit, Type } from '@angular/core';
 | 
				
			|||||||
import { FormGroup } from '@angular/forms';
 | 
					import { FormGroup } from '@angular/forms';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { AuthEmailSignupProfileField } from '@features/login/services/login-helper';
 | 
					import { AuthEmailSignupProfileField } from '@features/login/services/login-helper';
 | 
				
			||||||
 | 
					import { CoreUserProfileField } from '@features/user/services/user';
 | 
				
			||||||
import { CoreUserProfileFieldDelegate } from '@features/user/services/user-profile-field-delegate';
 | 
					import { CoreUserProfileFieldDelegate } from '@features/user/services/user-profile-field-delegate';
 | 
				
			||||||
import { CoreUtils } from '@services/utils/utils';
 | 
					import { CoreUtils } from '@services/utils/utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -28,7 +29,7 @@ import { CoreUtils } from '@services/utils/utils';
 | 
				
			|||||||
})
 | 
					})
 | 
				
			||||||
export class CoreUserProfileFieldComponent implements OnInit {
 | 
					export class CoreUserProfileFieldComponent implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Input() field?: AuthEmailSignupProfileField; // The profile field to be rendered.
 | 
					    @Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
 | 
				
			||||||
    @Input() signup = false; // True if editing the field in signup. Defaults to false.
 | 
					    @Input() signup = false; // True if editing the field in signup. Defaults to false.
 | 
				
			||||||
    @Input() edit = false; // True if editing the field. Defaults to false.
 | 
					    @Input() edit = false; // True if editing the field. Defaults to false.
 | 
				
			||||||
    @Input() form?: FormGroup; // Form where to add the form control. Required if edit=true or signup=true.
 | 
					    @Input() form?: FormGroup; // Form where to add the form control. Required if edit=true or signup=true.
 | 
				
			||||||
@ -54,7 +55,7 @@ export class CoreUserProfileFieldComponent implements OnInit {
 | 
				
			|||||||
        this.data.edit = CoreUtils.isTrueOrOne(this.edit);
 | 
					        this.data.edit = CoreUtils.isTrueOrOne(this.edit);
 | 
				
			||||||
        if (this.edit) {
 | 
					        if (this.edit) {
 | 
				
			||||||
            this.data.signup = CoreUtils.isTrueOrOne(this.signup);
 | 
					            this.data.signup = CoreUtils.isTrueOrOne(this.signup);
 | 
				
			||||||
            this.data.disabled = CoreUtils.isTrueOrOne(this.field.locked);
 | 
					            this.data.disabled = 'locked' in this.field && CoreUtils.isTrueOrOne(this.field.locked);
 | 
				
			||||||
            this.data.form = this.form;
 | 
					            this.data.form = this.form;
 | 
				
			||||||
            this.data.registerAuth = this.registerAuth;
 | 
					            this.data.registerAuth = this.registerAuth;
 | 
				
			||||||
            this.data.contextLevel = this.contextLevel;
 | 
					            this.data.contextLevel = this.contextLevel;
 | 
				
			||||||
@ -66,7 +67,7 @@ export class CoreUserProfileFieldComponent implements OnInit {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type CoreUserProfileFieldComponentData = {
 | 
					export type CoreUserProfileFieldComponentData = {
 | 
				
			||||||
    field?: AuthEmailSignupProfileField;
 | 
					    field?: AuthEmailSignupProfileField | CoreUserProfileField;
 | 
				
			||||||
    edit?: boolean;
 | 
					    edit?: boolean;
 | 
				
			||||||
    signup?: boolean;
 | 
					    signup?: boolean;
 | 
				
			||||||
    disabled?: boolean;
 | 
					    disabled?: boolean;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user