From da5d2fa2f85acbe144a51a6e19d5d81bff1c7c70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 22 Jul 2024 14:42:50 +0200 Subject: [PATCH] MOBILE-4616 compile: Import standalone components and new services --- src/core/components/components.module.ts | 16 +++++- src/core/features/compile/services/compile.ts | 49 ++++++++++--------- src/core/features/course/course.module.ts | 19 +++++++ 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/src/core/components/components.module.ts b/src/core/components/components.module.ts index dcc352b09..fb73105cf 100644 --- a/src/core/components/components.module.ts +++ b/src/core/components/components.module.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA, NgModule, Type } from '@angular/core'; import { CommonModule } from '@angular/common'; import { IonicModule } from '@ionic/angular'; import { TranslateModule } from '@ngx-translate/core'; @@ -66,6 +66,20 @@ import { CoreSheetModalComponent } from '@components/sheet-modal/sheet-modal'; import { CoreCourseImageComponent } from '@components/course-image/course-image'; import { CoreSitesListComponent } from './sites-list/sites-list'; +/** + * Get standalone components for site plugins. + * + * @returns Returns core standalone components. + */ +export async function getCoreStandaloneComponents(): Promise[]> { + // eslint-disable-next-line deprecation/deprecation + const { CoreStyleComponent } = await import('@components/style/style'); + + return [ + CoreStyleComponent, + ]; +} + @NgModule({ declarations: [ CoreAttachmentsComponent, diff --git a/src/core/features/compile/services/compile.ts b/src/core/features/compile/services/compile.ts index b253c6149..f85f156b8 100644 --- a/src/core/features/compile/services/compile.ts +++ b/src/core/features/compile/services/compile.ts @@ -16,12 +16,10 @@ import { Injectable, Injector, Component, - NgModule, ComponentRef, NO_ERRORS_SCHEMA, Type, Provider, - createNgModule, ViewContainerRef, } from '@angular/core'; import { @@ -43,7 +41,7 @@ import { getCoreServices } from '@/core/core.module'; import { getBlockServices } from '@features/block/block.module'; import { getCommentsServices } from '@features/comments/comments.module'; import { getContentLinksExportedObjects, getContentLinksServices } from '@features/contentlinks/contentlinks.module'; -import { getCourseExportedObjects, getCourseServices } from '@features/course/course.module'; +import { getCourseExportedObjects, getCourseServices, getCourseStandaloneComponents } from '@features/course/course.module'; import { getCoursesServices } from '@features/courses/courses.module'; import { getEditorServices } from '@features/editor/editor.module'; import { getEnrolServices } from '@features/enrol/enrol.module'; @@ -77,9 +75,13 @@ import { Md5 } from 'ts-md5/dist/md5'; // Import core classes that can be useful for site plugins. import { CoreSyncBaseProvider } from '@classes/base-sync'; import { CoreArray } from '@singletons/array'; +import { CoreColors } from '@singletons/colors'; import { CoreDirectivesRegistry } from '@singletons/directives-registry'; import { CoreDom } from '@singletons/dom'; import { CoreForms } from '@singletons/form'; +import { CoreKeyboard } from '@singletons/keyboard'; +import { CoreObject } from '@singletons/object'; +import { CorePath } from '@singletons/path'; import { CoreText } from '@singletons/text'; import { CoreTime } from '@singletons/time'; import { CoreUrl } from '@singletons/url'; @@ -116,6 +118,9 @@ import { getNotesServices } from '@addons/notes/notes.module'; import { getNotificationsServices } from '@addons/notifications/notifications.module'; import { getPrivateFilesServices } from '@addons/privatefiles/privatefiles.module'; +// Import standalone components used by site plugins. +import { getCoreStandaloneComponents } from '@components/components.module'; + // Import some addon modules that define components, directives and pipes. Only import the important ones. import { CorePromisedValue } from '@classes/promised-value'; import { CorePlatform } from '@services/platform'; @@ -157,6 +162,8 @@ export class CoreCompileProvider { getModAssignComponentModules, getModQuizComponentModules, getModWorkshopComponentModules, + getCoreStandaloneComponents, + getCourseStandaloneComponents, ]; protected componentId = 0; @@ -187,13 +194,6 @@ export class CoreCompileProvider { // Import the Angular compiler to be able to compile components in runtime. await import('@angular/compiler'); - // Create the component using the template and the class. - const component = Component({ - template, - host: { 'compiled-component-id': String(this.componentId++) }, - styles, - })(componentClass); - const lazyImports = await Promise.all(this.LAZY_IMPORTS.map(getModules => getModules())); const imports = [ ...lazyImports.flat(), @@ -201,20 +201,21 @@ export class CoreCompileProvider { ...extraImports, ]; + // Create the component using the template and the class. + const component = Component({ + template, + host: { 'compiled-component-id': String(this.componentId++) }, + styles, + standalone: true, + imports, + schemas: [NO_ERRORS_SCHEMA], + })(componentClass); + try { viewContainerRef.clear(); - // Now create the module containing the component. - const ngModuleRef = createNgModule( - NgModule({ imports, declarations: [component], schemas: [NO_ERRORS_SCHEMA] })(class {}), - this.injector, - ); - return viewContainerRef.createComponent( component, - { - environmentInjector: ngModuleRef, - }, ); } catch (error) { this.logger.error('Error compiling template', template); @@ -299,13 +300,17 @@ export class CoreCompileProvider { * Keeping this a bit more to avoid plugins breaking. */ instance['Network'] = CoreNetwork.instance; - instance['CoreSyncBaseProvider'] = CoreSyncBaseProvider; - instance['CoreArray'] = CoreArray; - instance['CoreDirectivesRegistry'] = CoreDirectivesRegistry; instance['CoreNetwork'] = CoreNetwork.instance; instance['CorePlatform'] = CorePlatform.instance; + instance['CoreSyncBaseProvider'] = CoreSyncBaseProvider; + instance['CoreArray'] = CoreArray; + instance['CoreColors'] = CoreColors; + instance['CoreDirectivesRegistry'] = CoreDirectivesRegistry; instance['CoreDom'] = CoreDom; instance['CoreForms'] = CoreForms; + instance['CoreKeyboard'] = CoreKeyboard; + instance['CoreObject'] = CoreObject; + instance['CorePath'] = CorePath; instance['CoreText'] = CoreText; instance['CoreTime'] = CoreTime; instance['CoreUrl'] = CoreUrl; diff --git a/src/core/features/course/course.module.ts b/src/core/features/course/course.module.ts index a3b1a83da..bddcbe8a4 100644 --- a/src/core/features/course/course.module.ts +++ b/src/core/features/course/course.module.ts @@ -87,6 +87,25 @@ export async function getCourseExportedObjects(): Promise[]> { + // eslint-disable-next-line deprecation/deprecation + const { CoreCourseModuleDescriptionComponent } = + await import('@features/course/components/module-description/module-description'); + // eslint-disable-next-line deprecation/deprecation + const { CoreCourseModuleManualCompletionComponent } = + await import('@features/course/components/module-manual-completion/module-manual-completion'); + + return [ + CoreCourseModuleDescriptionComponent, + CoreCourseModuleManualCompletionComponent, + ]; +} + const routes: Routes = [ { matcher: buildRegExpUrlMatcher(new RegExp(`^${COURSE_PAGE_NAME}(/deep)*`)),