Merge pull request #4127 from crazyserver/MOBILE-4616

Mobile 4616
main
Dani Palou 2024-07-25 15:52:24 +02:00 committed by GitHub
commit beac119e1e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
171 changed files with 1449 additions and 1128 deletions

View File

@ -69,8 +69,7 @@ jobs:
cat circular-dependencies
lines=$(cat circular-dependencies | wc -l)
echo "Total circular dependencies: $lines"
test $lines -ge 138
test $lines -le 148
test $lines -eq 135
- name: JavaScript code compatibility
run: |
npx check-es-compat www/*.js --polyfills="\{Array,String,TypedArray\}.prototype.at,Object.hasOwn"

View File

@ -7,10 +7,9 @@ module.exports = {
testMatch: ['**/?(*.)test.ts'],
collectCoverageFrom: [
'src/**/*.ts',
'!src/**/*.{test,stories}.ts',
'!src/**/*.test.ts',
'!src/assets/**/*',
'!src/testing/**/*',
'!src/storybook/**/*',
'!src/core/initializers/index.ts',
'!src/core/features/emulators/services/zip.ts',
],

View File

@ -454,7 +454,7 @@ class behat_app_helper extends behat_base {
$result = $this->zone_js("customUrlSchemes.handleCustomURL('$customurl')");
if ($result !== 'OK') {
throw new DriverException('Error handling url - ' . $result);
throw new DriverException('Error handling url - ' . $customurl . ' - '.$result);
}
if (!empty($successXPath)) {
// Wait until the page appears.

View File

@ -22,7 +22,7 @@ import { Translate } from '@singletons';
import { CoreUtils } from '@services/utils/utils';
import { CoreNavigator } from '@services/navigator';
import { CoreCourseHelper } from '@features/course/services/course-helper';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreSharedModule } from '@/core/shared.module';
/**
@ -103,7 +103,7 @@ export class AddonBlockActivityModulesComponent extends CoreBlockBaseComponent i
brandedIcons[mod.modname] = mod.branded;
// If this is not a theme image, leave it undefined to avoid having specific activity icons.
if (CoreUrlUtils.isThemeImageUrl(mod.modicon)) {
if (CoreUrl.isThemeImageUrl(mod.modicon)) {
modIcons[mod.modname] = mod.modicon;
}
});

View File

@ -26,7 +26,7 @@ import { CoreNavigator } from '@services/navigator';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { CoreArray } from '@singletons/array';
import { CoreEventObserver, CoreEvents } from '@singletons/events';
@ -79,7 +79,7 @@ export class AddonBlogIndexPage implements OnInit, OnDestroy {
...this.filter,
category: 'blog',
},
url: CoreUrlUtils.addParamsToUrl('/blog/index.php', {
url: CoreUrl.addParamsToUrl('/blog/index.php', {
...this.filter,
modid: this.filter.cmid,
cmid: undefined,

View File

@ -50,7 +50,7 @@ import {
import { CoreSwipeSlidesDynamicItemsManager } from '@classes/items-management/swipe-slides-dynamic-items-manager';
import moment from 'moment-timezone';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreTime } from '@singletons/time';
import { Translate } from '@singletons';
@ -132,7 +132,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
...params,
category: 'calendar',
},
url: CoreUrlUtils.addParamsToUrl('/calendar/view.php?view=month', params),
url: CoreUrl.addParamsToUrl('/calendar/view.php?view=month', params),
});
});
}

View File

@ -26,7 +26,7 @@ import { AddonCalendarOffline } from '../../services/calendar-offline';
import { CoreCategoryData, CoreCourses } from '@features/courses/services/courses';
import { CoreConstants } from '@/core/constants';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreTime } from '@singletons/time';
import { Translate } from '@singletons';
@ -103,7 +103,7 @@ export class AddonCalendarUpcomingEventsComponent implements OnInit, DoCheck, On
...params,
category: 'calendar',
},
url: CoreUrlUtils.addParamsToUrl('/calendar/view.php?view=upcoming', params),
url: CoreUrl.addParamsToUrl('/calendar/view.php?view=upcoming', params),
});
});
}

View File

@ -47,7 +47,7 @@ import {
import { CoreRoutedItemsManagerSourcesTracker } from '@classes/items-management/routed-items-manager-sources-tracker';
import { AddonCalendarEventsSource } from '@addons/calendar/classes/events-source';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreTime } from '@singletons/time';
/**
@ -201,7 +201,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy {
...params,
category: 'calendar',
},
url: CoreUrlUtils.addParamsToUrl('/calendar/view.php?view=day', params),
url: CoreUrl.addParamsToUrl('/calendar/view.php?view=day', params),
});
});
}

View File

@ -18,7 +18,7 @@ import { CoreSite } from '@classes/sites/site';
import { CoreNetwork } from '@services/network';
import { CoreTextUtils } from '@services/utils/text';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { CoreGroups } from '@services/groups';
import { CoreLocalNotifications } from '@services/local-notifications';
@ -362,14 +362,14 @@ export class AddonCalendarProvider {
// Add links to the days if needed.
if (dayStart && (!seenDay || !moment(seenDay).isSame(start, 'day'))) {
promises.push(this.getViewUrl('day', event.timestart, undefined, siteId).then((url) => {
dayStart = CoreUrlUtils.buildLink(url, dayStart);
dayStart = CoreUrl.buildLink(url, dayStart);
return;
}));
}
if (dayEnd && (!seenDay || !moment(seenDay).isSame(end, 'day'))) {
promises.push(this.getViewUrl('day', end / 1000, undefined, siteId).then((url) => {
dayEnd = CoreUrlUtils.buildLink(url, dayEnd);
dayEnd = CoreUrl.buildLink(url, dayEnd);
return;
}));
@ -398,7 +398,7 @@ export class AddonCalendarProvider {
// Add link to view the day.
const url = await this.getViewUrl('day', event.timestart, undefined, siteId);
return CoreUrlUtils.buildLink(url, this.getDayRepresentation(start, useCommonWords)) + ', ' + time;
return CoreUrl.buildLink(url, this.getDayRepresentation(start, useCommonWords)) + ', ' + time;
}
/**

View File

@ -40,7 +40,7 @@ import { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router';
import { AddonCompetencyCourseCompetenciesSource } from '@addons/competency/classes/competency-course-competencies-source';
import { CoreTime } from '@singletons/time';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
/**
* Page that displays the competency information.
@ -306,7 +306,7 @@ export class AddonCompetencyCompetencyPage implements OnInit, OnDestroy {
planstatus: this.planStatus,
userid: userId,
},
url: CoreUrlUtils.addParamsToUrl('/admin/tool/lp/user_competency_in_plan.php', {
url: CoreUrl.addParamsToUrl('/admin/tool/lp/user_competency_in_plan.php', {
planid: source.PLAN_ID,
userid: userId,
competencyid: compId,
@ -328,7 +328,7 @@ export class AddonCompetencyCompetencyPage implements OnInit, OnDestroy {
courseid: source.COURSE_ID,
userid: userId,
},
url: CoreUrlUtils.addParamsToUrl('/admin/tool/lp/user_competency_in_course.php', {
url: CoreUrl.addParamsToUrl('/admin/tool/lp/user_competency_in_course.php', {
courseid: source.COURSE_ID,
competencyid: compId,
userid: userId,

View File

@ -18,7 +18,7 @@ import { COURSE_PAGE_NAME } from '@features/course/constants';
import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate';
import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications';
import { CoreNavigator } from '@services/navigator';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { makeSingleton } from '@singletons';
import { AddonCompetency } from '../competency';
@ -49,7 +49,7 @@ export class AddonCompetencyPushClickHandlerService implements CorePushNotificat
* @inheritdoc
*/
async handleClick(notification: AddonCompetencyPushNotificationData): Promise<void> {
const contextUrlParams = CoreUrlUtils.extractUrlParams(notification.contexturl);
const contextUrlParams = CoreUrl.extractUrlParams(notification.contexturl);
if (notification.name == 'competencyplancomment') {
// Open the learning plan.

View File

@ -18,7 +18,7 @@ import { CoreFilterDefaultHandler } from '@features/filter/services/handlers/def
import { CoreFilterFilter, CoreFilterFormatTextOptions } from '@features/filter/services/filter';
import { makeSingleton } from '@singletons';
import { CoreH5PPlayerComponent } from '@features/h5p/components/h5p-player/h5p-player';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreH5PHelper } from '@features/h5p/classes/helper';
/**
@ -57,7 +57,7 @@ export class AddonFilterDisplayH5PHandlerService extends CoreFilterDefaultHandle
embeddedH5PIframes.forEach((iframe) => {
// Add the preventredirect param to allow authenticating if auto-login fails.
iframe.src = CoreUrlUtils.addParamsToUrl(iframe.src, { preventredirect: false });
iframe.src = CoreUrl.addParamsToUrl(iframe.src, { preventredirect: false });
// Add resizer script so the H5P has the right height.
CoreH5PHelper.addResizerScript();

View File

@ -23,6 +23,7 @@ import { CoreUtils } from '@services/utils/utils';
import { CoreEvents } from '@singletons/events';
import { CoreSite } from '@classes/sites/site';
import { makeSingleton } from '@singletons';
import { CoreWait } from '@singletons/wait';
/**
* Handler to support the MathJax filter.
@ -321,7 +322,7 @@ export class AddonFilterMathJaxLoaderHandlerService extends CoreFilterDefaultHan
return;
}
await CoreUtils.wait(250);
await CoreWait.wait(250);
await CoreUtils.ignoreErrors(this.waitForReady(retries + 1));
}

View File

@ -17,7 +17,7 @@ import { CorePromisedValue } from '@classes/promised-value';
import { CoreExternalContentDirective } from '@directives/external-content';
import { CoreLang } from '@services/lang';
import { CoreTextUtils } from '@services/utils/text';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { makeSingleton } from '@singletons';
import { CoreDirectivesRegistry } from '@singletons/directives-registry';
import { CoreEvents } from '@singletons/events';
@ -107,7 +107,7 @@ export class AddonFilterMediaPluginVideoJSService {
const dataSetupString = video.getAttribute('data-setup') || video.getAttribute('data-setup-lazy') || '{}';
const data = CoreTextUtils.parseJSON<VideoJSOptions>(dataSetupString, {});
const youtubeUrl = data.techOrder?.[0] == 'youtube' && CoreUrlUtils.getYoutubeEmbedUrl(data.sources?.[0]?.src);
const youtubeUrl = data.techOrder?.[0] == 'youtube' && CoreUrl.getYoutubeEmbedUrl(data.sources?.[0]?.src);
if (!youtubeUrl) {
return;

View File

@ -45,6 +45,8 @@ import { ActivatedRoute } from '@angular/router';
import { CoreConstants } from '@/core/constants';
import { CoreDom } from '@singletons/dom';
import { CoreKeyboard } from '@singletons/keyboard';
import { CoreText } from '@singletons/text';
import { CoreWait } from '@singletons/wait';
/**
* Page that displays a message discussion page.
@ -883,7 +885,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
return;
}
await CoreUtils.wait(400);
await CoreWait.wait(400);
await CoreUtils.ignoreErrors(this.waitForFetch());
}
@ -924,7 +926,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
*/
copyMessage(message: AddonMessagesConversationMessageFormatted): void {
const text = 'smallmessage' in message ? message.smallmessage || message.text || '' : message.text || '';
CoreUtils.copyToClipboard(CoreTextUtils.decodeHTMLEntities(text));
CoreText.copyToClipboard(CoreTextUtils.decodeHTMLEntities(text));
}
/**
@ -1071,7 +1073,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
this.setNewMessagesBadge(0);
// Leave time for the view to be rendered.
await CoreUtils.nextTicks(5);
await CoreWait.nextTicks(5);
if (!this.viewDestroyed && this.content) {
this.content.scrollToBottom(0);

View File

@ -32,6 +32,7 @@ import { CoreUser } from '@features/user/services/user';
import { CoreError } from '@classes/errors/error';
import { CoreTextErrorObject, CoreTextUtils } from '@services/utils/text';
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
import { CoreWait } from '@singletons/wait';
/**
* Service to sync messages.
@ -252,7 +253,7 @@ export class AddonMessagesSyncProvider extends CoreSyncBaseProvider<AddonMessage
// In some Moodle versions, wait 1 second to make sure timecreated is different.
// This is because there was a bug where messages with the same timecreated had a wrong order.
if (!groupMessagingEnabled && i < messages.length - 1) {
await CoreUtils.wait(1000);
await CoreWait.wait(1000);
}
}

View File

@ -16,7 +16,6 @@ import { Component, Input } from '@angular/core';
import { CoreCanceledError } from '@classes/errors/cancelederror';
import { CoreError } from '@classes/errors/error';
import { CoreDomUtils } from '@services/utils/dom';
import { AddonModAssignEditFeedbackModalComponent } from '../components/edit-feedback-modal/edit-feedback-modal';
import { AddonModAssignFeedbackCommentsTextData } from '../feedback/comments/services/handler';
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../services/assign';
@ -46,6 +45,9 @@ export class AddonModAssignFeedbackPluginBaseComponent implements IAddonModAssig
throw new CoreError('Cannot edit feedback');
}
const { AddonModAssignEditFeedbackModalComponent } =
await import('@addons/mod/assign/components/edit-feedback-modal/edit-feedback-modal');
// Create the navigation modal.
const modalData = await CoreDomUtils.openModal<AddonModAssignFeedbackCommentsTextData>({
component: AddonModAssignEditFeedbackModalComponent,

View File

@ -20,7 +20,6 @@ import { AddonModAssignIndexComponent } from './index/index';
import { AddonModAssignSubmissionComponent } from './submission/submission';
import { AddonModAssignSubmissionPluginComponent } from './submission-plugin/submission-plugin';
import { AddonModAssignFeedbackPluginComponent } from './feedback-plugin/feedback-plugin';
import { AddonModAssignEditFeedbackModalComponent } from './edit-feedback-modal/edit-feedback-modal';
@NgModule({
declarations: [
@ -28,7 +27,6 @@ import { AddonModAssignEditFeedbackModalComponent } from './edit-feedback-modal/
AddonModAssignSubmissionComponent,
AddonModAssignSubmissionPluginComponent,
AddonModAssignFeedbackPluginComponent,
AddonModAssignEditFeedbackModalComponent,
],
imports: [
CoreSharedModule,
@ -39,7 +37,6 @@ import { AddonModAssignEditFeedbackModalComponent } from './edit-feedback-modal/
AddonModAssignSubmissionComponent,
AddonModAssignSubmissionPluginComponent,
AddonModAssignFeedbackPluginComponent,
AddonModAssignEditFeedbackModalComponent,
],
})
export class AddonModAssignComponentsModule {}

View File

@ -20,6 +20,8 @@ import { CoreUtils } from '@services/utils/utils';
import { ModalController, Translate } from '@singletons';
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../../services/assign';
import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate';
import { CoreSharedModule } from '@/core/shared.module';
import { AddonModAssignComponentsModule } from '../components.module';
/**
* Modal that allows editing a feedback plugin.
@ -27,6 +29,11 @@ import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate
@Component({
selector: 'addon-mod-assign-edit-feedback-modal',
templateUrl: 'edit-feedback-modal.html',
standalone: true,
imports: [
CoreSharedModule,
AddonModAssignComponentsModule,
],
})
export class AddonModAssignEditFeedbackModalComponent {

View File

@ -16,7 +16,7 @@ import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { CoreCourseModuleMainActivityPage } from '@features/course/classes/main-activity-page';
import { AddonModAssignIndexComponent } from '../../components/index/index';
import { CoreNavigator } from '@services/navigator';
import { CoreUtils } from '@services/utils/utils';
import { CoreWait } from '@singletons/wait';
/**
* Page that displays an assign.
@ -44,7 +44,7 @@ export class AddonModAssignIndexPage extends CoreCourseModuleMainActivityPage<Ad
async ngAfterViewInit(): Promise<void> {
switch (this.action) {
case 'editsubmission':
await CoreUtils.waitFor(() => !!this.activityComponent?.submissionComponent, { timeout: 5000 });
await CoreWait.waitFor(() => !!this.activityComponent?.submissionComponent, { timeout: 5000 });
await this.activityComponent?.submissionComponent?.goToEdit();
break;

View File

@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
import { CoreCourseHelper } from '@features/course/services/course-helper';
import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate';
import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { makeSingleton } from '@singletons';
import { AddonModAssign } from '../assign';
@ -50,7 +50,7 @@ export class AddonModAssignPushClickHandlerService implements CorePushNotificati
* @returns Promise resolved when done.
*/
async handleClick(notification: NotificationData): Promise<void> {
const contextUrlParams = CoreUrlUtils.extractUrlParams(notification.contexturl);
const contextUrlParams = CoreUrl.extractUrlParams(notification.contexturl);
const courseId = Number(notification.courseid);
const moduleId = Number(contextUrlParams.id);

View File

@ -38,7 +38,7 @@ import {
AddonModBookTocChapter,
} from '../../services/book';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { ADDON_MOD_BOOK_COMPONENT, AddonModBookNavStyle } from '../../constants';
/**
@ -293,7 +293,7 @@ export class AddonModBookContentsPage implements OnInit, OnDestroy {
ws: 'mod_book_view_book',
name: this.module.name,
data: { id: this.module.instance, category: 'book', chapterid: chapterId },
url: CoreUrlUtils.addParamsToUrl(`/mod/book/view.php?id=${this.module.id}`, { chapterid: chapterId }),
url: CoreUrl.addParamsToUrl(`/mod/book/view.php?id=${this.module.id}`, { chapterid: chapterId }),
});
const currentChapterIndex = this.chapters.findIndex((chapter) => chapter.id == chapterId);

View File

@ -18,7 +18,7 @@ import { CoreTagFeedComponent } from '@features/tag/components/feed/feed';
import { CoreTagAreaHandler } from '@features/tag/services/tag-area-delegate';
import { CoreTagFeedElement, CoreTagHelper } from '@features/tag/services/tag-helper';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { makeSingleton } from '@singletons';
import { AddonModBook } from '../book';
@ -51,7 +51,7 @@ export class AddonModBookTagAreaHandlerService implements CoreTagAreaHandler {
// Find module ids of the returned books, they are needed by the link delegate.
await Promise.all(items.map(async (item) => {
const params = item.url ? CoreUrlUtils.extractUrlParams(item.url) : {};
const params = item.url ? CoreUrl.extractUrlParams(item.url) : {};
if (params.b && !params.id) {
const bookId = parseInt(params.b, 10);

View File

@ -30,6 +30,7 @@ import { AddonModChatFormattedMessage, AddonModChatHelper } from '../../services
import { CoreTime } from '@singletons/time';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { CoreKeyboard } from '@singletons/keyboard';
import { CoreWait } from '@singletons/wait';
/**
* Page that displays a chat session.
@ -358,7 +359,7 @@ export class AddonModChatChatPage implements OnInit, OnDestroy, CanLeave {
*/
async scrollToBottom(): Promise<void> {
// Need a timeout to leave time to the view to be rendered.
await CoreUtils.nextTick();
await CoreWait.nextTick();
if (!this.viewDestroyed) {
this.content?.scrollToBottom();
}

View File

@ -16,14 +16,12 @@ import { NgModule } from '@angular/core';
import { CoreSharedModule } from '@/core/shared.module';
import { CoreCourseComponentsModule } from '@features/course/components/components.module';
import { AddonModDataIndexComponent } from './index';
import { AddonModDataSearchComponent } from './search/search';
import { CoreCompileHtmlComponentModule } from '@features/compile/components/compile-html/compile-html.module';
import { AddonModDataActionsMenuComponent } from './actionsmenu/actionsmenu';
@NgModule({
declarations: [
AddonModDataIndexComponent,
AddonModDataSearchComponent,
AddonModDataActionsMenuComponent,
],
imports: [
@ -33,7 +31,6 @@ import { AddonModDataActionsMenuComponent } from './actionsmenu/actionsmenu';
],
exports: [
AddonModDataIndexComponent,
AddonModDataSearchComponent,
AddonModDataActionsMenuComponent,
],
})

View File

@ -40,8 +40,7 @@ import { AddonModDataHelper, AddonModDatDisplayFieldsOptions } from '../../servi
import { AddonModDataAutoSyncData, AddonModDataSyncResult } from '../../services/data-sync';
import { AddonModDataPrefetchHandler } from '../../services/handlers/prefetch-lazy';
import { AddonModDataComponentsCompileModule } from '../components-compile.module';
import { AddonModDataSearchComponent } from '../search/search';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreTime } from '@singletons/time';
import {
ADDON_MOD_DATA_AUTO_SYNCED,
@ -400,8 +399,10 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
* Display the chat users modal.
*/
async showSearch(): Promise<void> {
const { AddonModDataSearchModalComponent } = await import('@addons/mod/data/components/search-modal/search-modal');
const modalData = await CoreDomUtils.openModal<AddonModDataSearchDataParams>({
component: AddonModDataSearchComponent,
component: AddonModDataSearchModalComponent,
componentProps: {
search: this.search,
fields: this.fields,
@ -567,7 +568,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
this.analyticsLogEvent('mod_data_search_entries', {
data: params,
url: CoreUrlUtils.addParamsToUrl(`/mod/data/view.php?d=${this.database.id}`, params),
url: CoreUrl.addParamsToUrl(`/mod/data/view.php?d=${this.database.id}`, params),
});
}

View File

@ -30,16 +30,23 @@ import { AddonModDataHelper } from '../../services/data-helper';
import { AddonModDataComponentsCompileModule } from '../components-compile.module';
import { AddonModDataSearchDataParams } from '../index';
import { AddonModDataTemplateType } from '../../constants';
import { CoreSharedModule } from '@/core/shared.module';
import { CoreCompileHtmlComponentModule } from '../../../../../core/features/compile/components/compile-html/compile-html.module';
/**
* Page that displays the search modal.
*/
@Component({
selector: 'addon-mod-data-search-modal',
templateUrl: 'search.html',
templateUrl: 'search-modal.html',
styleUrls: ['../../data.scss', '../../data-forms.scss'],
standalone: true,
imports: [
CoreSharedModule,
CoreCompileHtmlComponentModule,
],
})
export class AddonModDataSearchComponent implements OnInit {
export class AddonModDataSearchModalComponent implements OnInit {
@ViewChild('searchFormEl') formElement!: ElementRef;

View File

@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
import { CoreCourseHelper } from '@features/course/services/course-helper';
import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate';
import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { makeSingleton } from '@singletons';
import { AddonModFeedbackHelper } from '../feedback-helper';
@ -48,7 +48,7 @@ export class AddonModFeedbackPushClickHandlerService implements CorePushNotifica
* @inheritdoc
*/
handleClick(notification: AddonModFeedbackPushNotificationData): Promise<void> {
const contextUrlParams = CoreUrlUtils.extractUrlParams(notification.contexturl!);
const contextUrlParams = CoreUrl.extractUrlParams(notification.contexturl!);
const courseId = Number(notification.courseid);
const moduleId = Number(contextUrlParams.id);

View File

@ -27,7 +27,7 @@ import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { Translate } from '@singletons';
@ -116,7 +116,7 @@ export class AddonModForumSearchPage implements OnInit {
query,
filters: JSON.stringify(this.resultsSource.getFilters()),
},
url: CoreUrlUtils.addParamsToUrl('/search/index.php', {
url: CoreUrl.addParamsToUrl('/search/index.php', {
q: query,
}),
});

View File

@ -24,7 +24,7 @@ import { CoreNetwork } from '@services/network';
import { CoreFileEntry } from '@services/file-helper';
import { CoreGroups } from '@services/groups';
import { CoreSitesCommonWSOptions, CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { CoreStatusWithWarningsWSResponse, CoreWSExternalFile, CoreWSExternalWarning, CoreWSStoredFile } from '@services/ws';
import { makeSingleton, Translate } from '@singletons';
@ -1312,7 +1312,7 @@ export class AddonModForumProvider {
protected translateWSPost(post: AddonModForumWSPost): AddonModForumPost {
(post as unknown as AddonModForumPost).tags = (post.tags || []).map((tag) => {
const viewUrl = (tag.urls && tag.urls.view) || '';
const params = CoreUrlUtils.extractUrlParams(viewUrl);
const params = CoreUrl.extractUrlParams(viewUrl);
return {
id: tag.tagid,

View File

@ -19,7 +19,7 @@ import { AddonModForum } from '@addons/mod/forum/services/forum';
import { CoreNavigator } from '@services/navigator';
import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate';
import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { makeSingleton } from '@singletons';
@ -56,7 +56,7 @@ export class AddonModForumPushClickHandlerService implements CorePushNotificatio
* @returns Promise resolved when done.
*/
async handleClick(notification: NotificationData): Promise<void> {
const contextUrlParams = CoreUrlUtils.extractUrlParams(notification.contexturl);
const contextUrlParams = CoreUrl.extractUrlParams(notification.contexturl);
const data = notification.customdata || {};
const courseId = Number(notification.courseid);
const discussionId = Number(contextUrlParams.d || data.discussionid);

View File

@ -23,7 +23,7 @@ import { CoreNavigator } from '@services/navigator';
import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@services/sites';
import { CoreSync } from '@services/sync';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { CoreWSExternalFile } from '@services/ws';
import { ModalController, Translate } from '@singletons';
@ -439,7 +439,7 @@ export class AddonModLessonPlayerPage implements OnInit, OnDestroy, CanLeave {
// Format review lesson if present.
if (this.eolData.reviewlesson) {
const params = CoreUrlUtils.extractUrlParams(<string> this.eolData.reviewlesson.value);
const params = CoreUrl.extractUrlParams(<string> this.eolData.reviewlesson.value);
if (!params || !params.pageid) {
// No pageid in the URL, the user cannot review (probably didn't answer any question).

View File

@ -23,7 +23,7 @@ import { CoreNetwork } from '@services/network';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreSync, CoreSyncResult } from '@services/sync';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { makeSingleton, Translate } from '@singletons';
import { CoreEvents } from '@singletons/events';
@ -463,7 +463,7 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
// Mark the retake as finished in a sync if it can be reviewed.
if (!ignoreBlock && response.data?.reviewlesson) {
const params = CoreUrlUtils.extractUrlParams(<string> response.data.reviewlesson.value);
const params = CoreUrl.extractUrlParams(<string> response.data.reviewlesson.value);
if (params.pageid) {
// The retake can be reviewed, mark it as finished. Don't block the user for this.
this.setRetakeFinishedInSync(lessonId, retake.retake, Number(params.pageid), siteId);

View File

@ -22,7 +22,7 @@ import { CoreFile } from '@services/file';
import { CorePlatform } from '@services/platform';
import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites';
import { CoreTextUtils } from '@services/utils/text';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws';
import { makeSingleton, Translate } from '@singletons';
@ -244,7 +244,7 @@ export class AddonModLtiProvider {
* @returns Promise resolved when the WS call is successful.
*/
async launch(url: string, params: AddonModLtiParam[]): Promise<void> {
if (!CoreUrlUtils.isHttpURL(url)) {
if (!CoreUrl.isHttpURL(url)) {
throw Translate.instant('addon.mod_lti.errorinvalidlaunchurl');
}

View File

@ -1,36 +0,0 @@
// (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 { CoreCourseComponentsModule } from '@features/course/components/components.module';
import { AddonModQuizPreflightModalComponent } from './preflight-modal.component';
export { AddonModQuizPreflightModalComponent };
@NgModule({
declarations: [
AddonModQuizPreflightModalComponent,
],
imports: [
CoreSharedModule,
CoreCourseComponentsModule,
],
exports: [
AddonModQuizPreflightModalComponent,
],
})
export class AddonModQuizPreflightModalComponentModule {}

View File

@ -22,6 +22,7 @@ import { ModalController, Translate } from '@singletons';
import { AddonModQuizAccessRuleDelegate } from '../../services/access-rules-delegate';
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '../../services/quiz';
import { CoreDom } from '@singletons/dom';
import { CoreSharedModule } from '@/core/shared.module';
/**
* Modal that renders the access rules for a quiz.
@ -29,6 +30,10 @@ import { CoreDom } from '@singletons/dom';
@Component({
selector: 'page-addon-mod-quiz-preflight-modal',
templateUrl: 'preflight-modal.html',
standalone: true,
imports: [
CoreSharedModule,
],
})
export class AddonModQuizPreflightModalComponent implements OnInit {

View File

@ -54,6 +54,7 @@ import { CoreDirectivesRegistry } from '@singletons/directives-registry';
import { CoreWSError } from '@classes/errors/wserror';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { ADDON_MOD_QUIZ_ATTEMPT_FINISHED_EVENT, AddonModQuizAttemptStates, ADDON_MOD_QUIZ_COMPONENT } from '../../constants';
import { CoreWait } from '@singletons/wait';
/**
* Page that allows attempting a quiz.
@ -831,7 +832,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
* @param slot Slot of the question to scroll to.
*/
protected async scrollToQuestion(slot: number): Promise<void> {
await CoreUtils.nextTick();
await CoreWait.nextTick();
await CoreDirectivesRegistry.waitDirectivesReady(this.elementRef.nativeElement, 'core-question');
await CoreDom.scrollToElement(
this.elementRef.nativeElement,

View File

@ -17,7 +17,7 @@ import { Injectable } from '@angular/core';
import { CoreCourseHelper } from '@features/course/services/course-helper';
import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate';
import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { makeSingleton } from '@singletons';
import { AddonModQuiz } from '../quiz';
@ -56,7 +56,7 @@ export class AddonModQuizPushClickHandlerService implements CorePushNotification
* @returns Promise resolved when done.
*/
async handleClick(notification: AddonModQuizPushNotificationData): Promise<void> {
const contextUrlParams = CoreUrlUtils.extractUrlParams(notification.contexturl || '');
const contextUrlParams = CoreUrl.extractUrlParams(notification.contexturl || '');
const data = notification.customdata || {};
const courseId = Number(notification.courseid);

View File

@ -269,7 +269,7 @@ export class AddonModQuizHelperProvider {
}
const { AddonModQuizPreflightModalComponent } =
await import('@addons/mod/quiz/components/preflight-modal/preflight-modal.module');
await import('@addons/mod/quiz/components/preflight-modal/preflight-modal');
// Create and show the modal.
const modalData = await CoreDomUtils.openModal<Record<string, string>>({

View File

@ -49,6 +49,7 @@ import {
ADDON_MOD_SCORM_DATA_AUTO_SYNCED,
ADDON_MOD_SCORM_PAGE_NAME,
} from '../../constants';
import { CoreWait } from '@singletons/wait';
/**
* Component that displays a SCORM entry page.
@ -616,7 +617,7 @@ export class AddonModScormIndexComponent extends CoreCourseModuleMainActivityCom
if (CoreSync.isBlocked(ADDON_MOD_SCORM_COMPONENT, this.scorm.id) && retries < 5) {
// Sync is currently blocked, this can happen when SCORM player is left. Retry in a bit.
await CoreUtils.wait(400);
await CoreWait.wait(400);
return this.sync(retries + 1);
}

View File

@ -43,6 +43,7 @@ import {
ADDON_MOD_SCORM_LAUNCH_PREV_SCO_EVENT,
ADDON_MOD_SCORM_UPDATE_TOC_EVENT,
} from '../../constants';
import { CoreWait } from '@singletons/wait';
/**
* Page that allows playing a SCORM.
@ -436,7 +437,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
// Changing SCO. First unload the existing SCO to make sure the callback to send the data has been called.
this.src = '';
await CoreUtils.nextTick();
await CoreWait.nextTick();
// Load the SCO in the existing model.
this.dataModel.loadSco(sco.id);

View File

@ -23,7 +23,7 @@ import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@
import { CoreSync } from '@services/sync';
import { CoreTextUtils } from '@services/utils/text';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { CoreWS, CoreWSExternalFile, CoreWSExternalWarning, CoreWSFile, CoreWSPreSets } from '@services/ws';
import { makeSingleton, Translate } from '@singletons';
@ -1328,7 +1328,7 @@ export class AddonModScormProvider {
protected isExternalLink(link: string): boolean {
link = link.toLowerCase();
if (link.match(/^https?:\/\//i) && !CoreUrlUtils.isLocalFileUrl(link)) {
if (link.match(/^https?:\/\//i) && !CoreUrl.isLocalFileUrl(link)) {
return true;
} else if (link.substring(0, 4) == 'www.') {
return true;

View File

@ -26,7 +26,7 @@ import { makeSingleton } from '@singletons';
import { AddonModUrl } from '../url';
import { AddonModUrlHelper } from '../url-helper';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreMimetypeUtils } from '@services/utils/mimetype';
import { ADDON_MOD_URL_ADDON_NAME, ADDON_MOD_URL_MODNAME, ADDON_MOD_URL_PAGE_NAME } from '../../constants';
@ -122,14 +122,14 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
return modIcon;
}
const component = CoreUrlUtils.getThemeImageUrlParam(module.modicon, 'component');
const component = CoreUrl.getThemeImageUrlParam(module.modicon, 'component');
if (component === this.modName) {
return modIcon;
}
let icon: string | undefined;
let image = CoreUrlUtils.getThemeImageUrlParam(module.modicon, 'image');
let image = CoreUrl.getThemeImageUrlParam(module.modicon, 'image');
if (image.startsWith('f/')) {
// Remove prefix, and hyphen + numbered suffix.
image = image.substring(2).replace(/-[0-9]+$/, '');

View File

@ -19,7 +19,6 @@ import { CoreCourseComponentsModule } from '@features/course/components/componen
import { CoreEditorComponentsModule } from '@features/editor/components/components.module';
import { CoreSharedModule } from '@/core/shared.module';
import { AddonModWorkshopAssessmentComponentsModule } from '@addons/mod/workshop/assessment/assesment-components.module';
import { AddonModWorkshopPhaseInfoComponent } from './phase/phase';
import { AddonModWorkshopAssessmentComponent } from './assessment/assessment';
import { AddonModWorkshopAssessmentStrategyComponent } from './assessment-strategy/assessment-strategy';
@ -27,7 +26,6 @@ import { AddonModWorkshopAssessmentStrategyComponent } from './assessment-strate
declarations: [
AddonModWorkshopIndexComponent,
AddonModWorkshopSubmissionComponent,
AddonModWorkshopPhaseInfoComponent,
AddonModWorkshopAssessmentComponent,
AddonModWorkshopAssessmentStrategyComponent,
],
@ -40,7 +38,6 @@ import { AddonModWorkshopAssessmentStrategyComponent } from './assessment-strate
exports: [
AddonModWorkshopIndexComponent,
AddonModWorkshopSubmissionComponent,
AddonModWorkshopPhaseInfoComponent,
AddonModWorkshopAssessmentComponent,
AddonModWorkshopAssessmentStrategyComponent,
],

View File

@ -48,7 +48,6 @@ import {
AddonModWorkshopAutoSyncData,
AddonModWorkshopSyncResult,
} from '../../services/workshop-sync';
import { AddonModWorkshopPhaseInfoComponent } from '../phase/phase';
import {
ADDON_MOD_WORKSHOP_ASSESSMENT_SAVED,
ADDON_MOD_WORKSHOP_AUTO_SYNCED,
@ -398,9 +397,11 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
if (!this.phases || !this.workshop) {
return;
}
const { AddonModWorkshopPhaseInfoModalComponent } =
await import('@addons/mod/workshop/components/phase-modal/phase-modal');
const modalData = await CoreDomUtils.openModal<boolean>({
component: AddonModWorkshopPhaseInfoComponent,
component: AddonModWorkshopPhaseInfoModalComponent,
componentProps: {
phases: CoreUtils.objectToArray(this.phases),
workshopPhase: this.workshop.phase,

View File

@ -17,14 +17,19 @@ import { CoreUtils } from '@services/utils/utils';
import { ModalController } from '@singletons';
import { AddonModWorkshopPhaseData, AddonModWorkshopPhaseTaskData } from '../../services/workshop';
import { AddonModWorkshopPhase } from '../../constants';
import { CoreSharedModule } from '@/core/shared.module';
/**
* Page that displays the phase info modal.
*/
@Component({
templateUrl: 'phase.html',
templateUrl: 'phase-modal.html',
standalone: true,
imports: [
CoreSharedModule,
],
})
export class AddonModWorkshopPhaseInfoComponent implements OnInit {
export class AddonModWorkshopPhaseInfoModalComponent implements OnInit {
@Input() phases!: AddonModWorkshopPhaseDataWithSwitch[];
@Input() workshopPhase!: AddonModWorkshopPhase;

View File

@ -19,12 +19,17 @@ import { CoreDomUtils, ToastDuration } from '@services/utils/dom';
import { CoreForms } from '@singletons/form';
import { ModalController } from '@singletons';
import { CoreKeyboard } from '@singletons/keyboard';
import { CoreSharedModule } from '@/core/shared.module';
/**
* Component that displays a text area for composing a note.
*/
@Component({
templateUrl: 'add-modal.html',
standalone: true,
imports: [
CoreSharedModule,
],
})
export class AddonNotesAddComponent {

View File

@ -1,30 +0,0 @@
// (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 { CoreSharedModule } from '@/core/shared.module';
import { NgModule } from '@angular/core';
import { AddonNotesAddComponent } from './add/add-modal';
@NgModule({
declarations: [
AddonNotesAddComponent,
],
imports: [
CoreSharedModule,
],
exports: [
AddonNotesAddComponent,
],
})
export class AddonNotesComponentsModule {}

View File

@ -21,7 +21,6 @@ import { AddonNotesSyncCronHandler } from './services/handlers/sync-cron';
import { AddonNotesUserHandler } from './services/handlers/user';
import { CORE_SITE_SCHEMAS } from '@services/sites';
import { NOTES_OFFLINE_SITE_SCHEMA } from './services/database/notes';
import { AddonNotesComponentsModule } from './components/components.module';
import { Routes } from '@angular/router';
import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-routing.module';
import { CoreCourseIndexRoutingModule } from '@features/course/course-routing.module';
@ -54,7 +53,6 @@ const routes: Routes = [
imports: [
CoreMainMenuTabRoutingModule.forChild(routes),
CoreCourseIndexRoutingModule.forChild({ children: routes }),
AddonNotesComponentsModule,
],
providers: [
{

View File

@ -13,7 +13,7 @@
// limitations under the License.
import { CoreConstants } from '@/core/constants';
import { AddonNotesAddComponent, AddonNotesAddModalReturn } from '@addons/notes/components/add/add-modal';
import { AddonNotesAddModalReturn } from '@addons/notes/components/add/add-modal';
import { AddonNotes, AddonNotesNoteFormatted, AddonNotesPublishState } from '@addons/notes/services/notes';
import { AddonNotesOffline } from '@addons/notes/services/notes-offline';
import { AddonNotesSync, AddonNotesSyncProvider } from '@addons/notes/services/notes-sync';
@ -26,7 +26,7 @@ import { CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites';
import { CoreDomUtils, ToastDuration } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { Translate } from '@singletons';
import { CoreEventObserver, CoreEvents } from '@singletons/events';
@ -194,6 +194,8 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
this.logViewAdd();
const { AddonNotesAddComponent } = await import('@addons/notes/components/add/add-modal');
const modalData = await CoreDomUtils.openModal<AddonNotesAddModalReturn>({
component: AddonNotesAddComponent,
componentProps: {
@ -311,7 +313,7 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
ws: 'core_notes_view_notes',
name: Translate.instant('addon.notes.notes'),
data: { courseid: this.courseId, userid: this.userId || 0, category: 'notes' },
url: CoreUrlUtils.addParamsToUrl('/notes/index.php', {
url: CoreUrl.addParamsToUrl('/notes/index.php', {
user: this.userId,
course: this.courseId !== CoreSites.getCurrentSiteHomeId() ? this.courseId : undefined,
}),
@ -327,7 +329,7 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
ws: 'core_notes_create_notes',
name: Translate.instant('addon.notes.notes'),
data: { courseid: this.courseId, userid: this.userId || 0, category: 'notes' },
url: CoreUrlUtils.addParamsToUrl('/notes/edit.php', {
url: CoreUrl.addParamsToUrl('/notes/edit.php', {
courseid: this.courseId,
userid: this.userId,
publishstate: this.type === 'personal' ? 'draft' : (this.type === 'course' ? 'public' : 'site'),

View File

@ -14,12 +14,12 @@
import { CoreFormatTextDirective } from '@directives/format-text';
import { CoreTextUtils } from '@services/utils/text';
import { CoreUtils } from '@services/utils/utils';
import { CoreDirectivesRegistry } from '@singletons/directives-registry';
import { CoreCoordinates, CoreDom } from '@singletons/dom';
import { CoreEventObserver } from '@singletons/events';
import { CoreLogger } from '@singletons/logger';
import { AddonModQuizDdwtosQuestionData } from '../component/ddwtos';
import { CoreWait } from '@singletons/wait';
/**
* Class to make a question of ddwtos type work.
@ -491,7 +491,7 @@ export class AddonQtypeDdwtosQuestion {
} else {
// Group items should always have a parent, add a fallback just in case.
await CoreDom.waitToBeInDOM(groupItems[0]);
await CoreUtils.nextTicks(5);
await CoreWait.nextTicks(5);
}
// Find max height and width.

View File

@ -18,7 +18,7 @@ import { CoreQuestionHelper } from '@features/question/services/question-helper'
import { CoreDomUtils } from '@services/utils/dom';
import { ItemReorderEventDetail } from '@ionic/angular';
import { Translate } from '@singletons';
import { CoreUtils } from '@services/utils/utils';
import { CoreWait } from '@singletons/wait';
import { CorePlatform } from '@services/platform';
/**
@ -153,7 +153,7 @@ export class AddonQtypeOrderingComponent extends CoreQuestionBaseComponent<Addon
complete: () => {}, // eslint-disable-line @typescript-eslint/no-empty-function
});
await CoreUtils.nextTick();
await CoreWait.nextTick();
// When moving an item to the first or last position, the button that was clicked will be hidden. In this case, we need to
// focus the other button. Otherwise, re-focus the same button since the focus is lost in some cases.

View File

@ -27,6 +27,7 @@ import { CorePlatform } from '@services/platform';
import { CoreLogger } from '@singletons/logger';
import { CorePromisedValue } from '@classes/promised-value';
import { register } from 'swiper/element/bundle';
import { CoreWait } from '@singletons/wait';
register();
@ -83,7 +84,7 @@ export class AppComponent implements OnInit, AfterViewInit {
// Check if the path changes due to the back navigation handler, to know if we're at root level.
// Ionic doc recommends IonRouterOutlet.canGoBack, but there's no easy way to get the current outlet from here.
// The path seems to change immediately (0 ms timeout), but use 50ms just in case.
await CoreUtils.wait(50);
await CoreWait.wait(50);
if (CoreNavigator.getCurrentPath() != initialPath) {
// Ionic has navigated back, nothing else to do.

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { CoreUtils } from '@services/utils/utils';
import { CoreWait } from '@singletons/wait';
import { LoadingController } from '@singletons';
/**
@ -105,7 +105,7 @@ export class CoreIonLoadingElement {
// Wait a bit before presenting the modal, to prevent it being displayed if dismiss is called fast.
this.scheduled = true;
await CoreUtils.wait(40);
await CoreWait.wait(40);
if (!this.scheduled) {
return;

View File

@ -19,6 +19,7 @@ import { AsyncDirective } from './async-directive';
import { PageLoadsManager } from './page-loads-manager';
import { CorePromisedValue } from './promised-value';
import { WSObservable } from './sites/authenticated-site';
import { CoreWait } from '@singletons/wait';
/**
* Class to watch requests from a page load (including requests from page sub-components).
@ -111,7 +112,7 @@ export class PageLoadWatcher {
this.checkHasLoaded();
// Subscription variable might not be set because the observable completed immediately. Wait for next tick.
await CoreUtils.nextTick();
await CoreWait.nextTick();
subscription?.unsubscribe();
};

View File

@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { CoreRefreshButtonModalComponent } from '@components/refresh-button-modal/refresh-button-modal';
import { CoreNavigator } from '@services/navigator';
import { CoreDomUtils } from '@services/utils/dom';
import { Subject } from 'rxjs';
@ -129,6 +128,9 @@ export class PageLoadsManager {
* Notify the user, asking him if he wants to update the data.
*/
protected async notifyUser(): Promise<void> {
const { CoreRefreshButtonModalComponent }
= await import('@components/refresh-button-modal/refresh-button-modal');
await CoreDomUtils.openModal<boolean>({
component: CoreRefreshButtonModalComponent,
cssClass: 'core-modal-no-background core-modal-fullscreen',

View File

@ -39,9 +39,9 @@ import { CoreSiteError } from '@classes/errors/siteerror';
import { CoreUserAuthenticatedSupportConfig } from '@features/user/classes/support/authenticated-support-config';
import { CoreSiteInfo, CoreSiteInfoResponse, CoreSitePublicConfigResponse, CoreUnauthenticatedSite } from './unauthenticated-site';
import { Md5 } from 'ts-md5';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreSiteWSCacheRecord } from '@services/database/sites';
import { CoreErrorLogs } from '@singletons/error-logs';
import { CoreWait } from '@singletons/wait';
/**
* Class that represents a site (combination of site + user) where the user has authenticated but the site hasn't been validated
@ -1267,11 +1267,33 @@ export class CoreAuthenticatedSite extends CoreUnauthenticatedSite {
*
* @param page Docs page to go to.
* @returns Promise resolved with the Moodle docs URL.
*
* @deprecated since 4.5. Not needed anymore.
*/
getDocsUrl(page?: string): Promise<string> {
async getDocsUrl(page?: string): Promise<string> {
const release = this.infos?.release ? this.infos.release : undefined;
let docsUrl = 'https://docs.moodle.org/en/' + page;
return CoreUrlUtils.getDocsUrl(release, page);
if (release !== undefined) {
// Remove this part of the function if this file only uses CoreSites here.
const version = CoreSites.getMajorReleaseNumber(release).replace('.', '');
// Check is a valid number.
if (Number(version) >= 24) {
// Append release number.
docsUrl = docsUrl.replace('https://docs.moodle.org/', 'https://docs.moodle.org/' + version + '/');
}
}
try {
// Remove this part of the function if this file only uses CoreLang here.
let lang = CoreLang.getCurrentLanguageSync(CoreLangFormat.LMS);
lang = CoreLang.getParentLanguage() || lang;
return docsUrl.replace('/en/', '/' + lang + '/');
} catch {
return docsUrl;
}
}
/**
@ -1584,7 +1606,7 @@ export function chainRequests<T, O extends ObservableInput<any>>(
firstValue = false;
// Wait to see if the observable is completed (no more values).
await CoreUtils.nextTick();
await CoreWait.nextTick();
if (isCompleted) {
// Current request only returns cached data. Let chained requests update in background.
@ -1601,7 +1623,7 @@ export function chainRequests<T, O extends ObservableInput<any>>(
complete: async () => {
isCompleted = true;
await CoreUtils.nextTick();
await CoreWait.nextTick();
subscriber.complete();
},

View File

@ -27,7 +27,7 @@ import {
import { CoreDomUtils } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils, CoreUtilsOpenInBrowserOptions } from '@services/utils/utils';
import { CoreConstants } from '@/core/constants';
import { SQLiteDB } from '@classes/sqlitedb';
@ -380,7 +380,7 @@ export class CoreSite extends CoreAuthenticatedSite {
const accessKey = this.tokenPluginFileWorks || this.tokenPluginFileWorks === undefined ?
this.infos && this.infos.userprivateaccesskey : undefined;
return CoreUrlUtils.fixPluginfileURL(url, this.token || '', this.siteUrl, accessKey);
return CoreUrl.fixPluginfileURL(url, this.token || '', this.siteUrl, accessKey);
}
/**
@ -775,7 +775,7 @@ export class CoreSite extends CoreAuthenticatedSite {
* @returns Promise resolved with boolean: whether it works or not.
*/
checkTokenPluginFile(url: string): Promise<boolean> {
if (!CoreUrlUtils.canUseTokenPluginFile(url, this.siteUrl, this.infos && this.infos.userprivateaccesskey)) {
if (!CoreUrl.canUseTokenPluginFile(url, this.siteUrl, this.infos && this.infos.userprivateaccesskey)) {
// Cannot use tokenpluginfile.
return Promise.resolve(false);
} else if (this.tokenPluginFileWorks !== undefined) {

View File

@ -17,7 +17,7 @@ import { CoreError } from '@classes/errors/error';
import { CoreLoginHelper } from '@features/login/services/login-helper';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreTextUtils } from '@services/utils/text';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl, CoreUrlPartNames } from '@singletons/url';
import { CoreWS, CoreWSAjaxPreSets, CoreWSExternalWarning } from '@services/ws';
import { CorePath } from '@singletons/path';
@ -37,7 +37,10 @@ export class CoreUnauthenticatedSite {
* @param publicConfig Site public config.
*/
constructor(siteUrl: string, publicConfig?: CoreSitePublicConfigResponse) {
this.siteUrl = CoreUrlUtils.removeUrlParams(siteUrl); // Make sure the URL doesn't have params.
this.siteUrl = CoreUrl.removeUrlParts(
siteUrl,
[CoreUrlPartNames.Query, CoreUrlPartNames.Fragment],
); // Make sure the URL doesn't have params.
if (publicConfig) {
this.setPublicConfig(publicConfig);
}
@ -143,7 +146,7 @@ export class CoreUnauthenticatedSite {
* @returns URL with params.
*/
createSiteUrl(path: string, params?: Record<string, unknown>, anchor?: string): string {
return CoreUrlUtils.addParamsToUrl(CorePath.concatenatePaths(this.siteUrl, path), params, anchor);
return CoreUrl.addParamsToUrl(CorePath.concatenatePaths(this.siteUrl, path), params, anchor);
}
/**
@ -157,8 +160,10 @@ export class CoreUnauthenticatedSite {
return false;
}
const siteUrl = CoreTextUtils.addEndingSlash(CoreUrlUtils.removeProtocolAndWWW(this.siteUrl));
url = CoreTextUtils.addEndingSlash(CoreUrlUtils.removeProtocolAndWWW(url));
const siteUrl = CoreTextUtils.addEndingSlash(
CoreUrl.removeUrlParts(this.siteUrl, [CoreUrlPartNames.Protocol, CoreUrlPartNames.WWWInDomain]),
);
url = CoreTextUtils.addEndingSlash(CoreUrl.removeUrlParts(url, [CoreUrlPartNames.Protocol, CoreUrlPartNames.WWWInDomain]));
return url.indexOf(siteUrl) == 0;
}
@ -244,7 +249,10 @@ export class CoreUnauthenticatedSite {
// Use the wwwroot returned by the server.
if (config.httpswwwroot) {
this.siteUrl = CoreUrlUtils.removeUrlParams(config.httpswwwroot); // Make sure the URL doesn't have params.
this.siteUrl = CoreUrl.removeUrlParts(
config.httpswwwroot,
[CoreUrlPartNames.Query, CoreUrlPartNames.Fragment],
); // Make sure the URL doesn't have params.
}
return config;
@ -268,7 +276,7 @@ export class CoreUnauthenticatedSite {
* @returns Whether it's a site file URL.
*/
isSitePluginFileUrl(url: string): boolean {
const isPluginFileUrl = CoreUrlUtils.isPluginFileUrl(url) || CoreUrlUtils.isTokenPluginFileUrl(url);
const isPluginFileUrl = CoreUrl.isPluginFileUrl(url) || CoreUrl.isTokenPluginFileUrl(url);
if (!isPluginFileUrl) {
return false;
}
@ -283,7 +291,7 @@ export class CoreUnauthenticatedSite {
* @returns Whether it's a site theme image URL.
*/
isSiteThemeImageUrl(url: string): boolean {
if (!CoreUrlUtils.isThemeImageUrl(url)) {
if (!CoreUrl.isThemeImageUrl(url)) {
return false;
}

View File

@ -31,7 +31,7 @@ import { CoreSettingsHelper } from '@features/settings/services/settings-helper'
import { CoreAriaRoleTab, CoreAriaRoleTabFindable } from './aria-role-tab';
import { CoreEventObserver } from '@singletons/events';
import { CoreDom } from '@singletons/dom';
import { CoreUtils } from '@services/utils/utils';
import { CoreWait } from '@singletons/wait';
import { CoreError } from './errors/error';
import { CorePromisedValue } from './promised-value';
import { AsyncDirective } from './async-directive';
@ -218,7 +218,7 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements AfterViewIn
this.slideChanged();
this.swiper.update();
await CoreUtils.nextTick();
await CoreWait.nextTick();
if (!this.hasSliddenToInitial && this.selectedIndex && this.selectedIndex >= this.swiper.slidesPerViewDynamic()) {
this.hasSliddenToInitial = true;
@ -344,7 +344,7 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements AfterViewIn
}
this.maxSlides = 3;
await CoreUtils.nextTick();
await CoreWait.nextTick();
if (!this.swiper.width) {
return;

View File

@ -13,7 +13,7 @@
// limitations under the License.
import { CoreQueueRunner } from '@classes/queue-runner';
import { CoreUtils } from '@services/utils/utils';
import { CoreWait } from '@singletons/wait';
describe('CoreQueueRunner', () => {
@ -26,7 +26,7 @@ describe('CoreQueueRunner', () => {
// Act
await Promise.all(range.map((i) => lock.run(async () => {
await CoreUtils.wait(Math.floor(Math.random() * 10));
await CoreWait.wait(Math.floor(Math.random() * 10));
items.push(`Item #${i}`);
})));

View File

@ -61,7 +61,6 @@ import { CoreSwipeSlidesComponent } from './swipe-slides/swipe-slides';
import { CoreSwipeNavigationTourComponent } from './swipe-navigation-tour/swipe-navigation-tour';
import { CoreMessageComponent } from './message/message';
import { CoreGroupSelectorComponent } from './group-selector/group-selector';
import { CoreRefreshButtonModalComponent } from './refresh-button-modal/refresh-button-modal';
import { CoreSheetModalComponent } from '@components/sheet-modal/sheet-modal';
import { CoreCourseImageComponent } from '@components/course-image/course-image';
import { CoreSitesListComponent } from './sites-list/sites-list';
@ -123,7 +122,6 @@ export async function getCoreStandaloneComponents(): Promise<Type<unknown>[]> {
CoreSpacerComponent,
CoreHorizontalScrollControlsComponent,
CoreSwipeNavigationTourComponent,
CoreRefreshButtonModalComponent,
CoreSheetModalComponent,
CoreSitesListComponent,
],
@ -177,7 +175,6 @@ export async function getCoreStandaloneComponents(): Promise<Type<unknown>[]> {
CoreSpacerComponent,
CoreHorizontalScrollControlsComponent,
CoreSwipeNavigationTourComponent,
CoreRefreshButtonModalComponent,
CoreSheetModalComponent,
CoreSitesListComponent,
],

View File

@ -20,7 +20,7 @@ import { CorePluginFileDelegate } from '@services/plugin-file-delegate';
import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreMimetypeUtils } from '@services/utils/mimetype';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils, CoreUtilsOpenFileOptions, OpenFileAction } from '@services/utils/utils';
import { CoreTextUtils } from '@services/utils/text';
import { DownloadStatus } from '@/core/constants';
@ -195,10 +195,10 @@ export class CoreFileComponent implements OnInit, OnDestroy {
if (!this.canDownload || !this.state || this.state === DownloadStatus.NOT_DOWNLOADABLE) {
// File cannot be downloaded, just open it.
if (CoreUrlUtils.isLocalFileUrl(this.fileUrl)) {
if (CoreUrl.isLocalFileUrl(this.fileUrl)) {
CoreUtils.openFile(this.fileUrl);
} else {
CoreUtils.openOnlineFile(CoreUrlUtils.unfixPluginfileURL(this.fileUrl));
CoreUtils.openOnlineFile(CoreUrl.unfixPluginfileURL(this.fileUrl));
}
return;

View File

@ -19,7 +19,7 @@ import { SafeResourceUrl } from '@angular/platform-browser';
import { CoreFile } from '@services/file';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreIframeUtils } from '@services/utils/iframe';
import { CoreUtils } from '@services/utils/utils';
import { DomSanitizer, Router, StatusBar } from '@singletons';
@ -29,7 +29,6 @@ import { Subscription } from 'rxjs';
import { filter } from 'rxjs/operators';
import { NavigationStart } from '@angular/router';
import { CoreSites } from '@services/sites';
import { CoreUrl } from '@singletons/url';
@Component({
selector: 'core-iframe',
@ -118,7 +117,7 @@ export class CoreIframeComponent implements OnChanges, OnDestroy {
}
// Show loading only with external URLs.
this.loading = !this.src || !CoreUrlUtils.isLocalFileUrl(this.src);
this.loading = !this.src || !CoreUrl.isLocalFileUrl(this.src);
if (this.loading) {
setTimeout(() => {
@ -197,8 +196,8 @@ export class CoreIframeComponent implements OnChanges, OnDestroy {
this.launchExternalLabel = undefined;
if (url && !CoreUrlUtils.isLocalFileUrl(url)) {
url = CoreUrlUtils.getYoutubeEmbedUrl(url) || url;
if (url && !CoreUrl.isLocalFileUrl(url)) {
url = CoreUrl.getYoutubeEmbedUrl(url) || url;
this.displayHelp = CoreIframeUtils.shouldDisplayHelpForUrl(url);
const currentSite = CoreSites.getCurrentSite();

View File

@ -14,7 +14,7 @@
import { Component, Input, Output, EventEmitter, OnChanges, SimpleChange, ViewChild, ElementRef } from '@angular/core';
import { IonInfiniteScroll } from '@ionic/angular';
import { CoreUtils } from '@services/utils/utils';
import { CoreWait } from '@singletons/wait';
const THRESHOLD = .15; // % of the scroll element height that must be close to the edge to consider loading more items necessary.
@ -77,8 +77,8 @@ export class CoreInfiniteLoadingComponent implements OnChanges {
}
// Wait to allow items to render and scroll content to grow.
await CoreUtils.nextTick();
await CoreUtils.waitFor(() => scrollElement.scrollHeight > scrollElement.clientHeight, { timeout: 1000 });
await CoreWait.nextTick();
await CoreWait.waitFor(() => scrollElement.scrollHeight > scrollElement.clientHeight, { timeout: 1000 });
// Calculate distance from edge.
const infiniteHeight = this.hostElement.getBoundingClientRect().height;
@ -116,7 +116,7 @@ export class CoreInfiniteLoadingComponent implements OnChanges {
*/
async complete(): Promise<void> {
// Wait a bit before allowing loading more, otherwise it could be re-triggered automatically when it shouldn't.
await CoreUtils.wait(400);
await CoreWait.wait(400);
await this.completeLoadMore();
}

View File

@ -21,6 +21,7 @@ import { CoreDirectivesRegistry } from '@singletons/directives-registry';
import { CorePromisedValue } from '@classes/promised-value';
import { AsyncDirective } from '@classes/async-directive';
import { CorePlatform } from '@services/platform';
import { CoreWait } from '@singletons/wait';
/**
* Component to show a loading spinner and message while data is being loaded.
@ -72,13 +73,13 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A
// Throttle 20ms to let mutations resolve.
const throttleMutation = CoreUtils.throttle(async () => {
await CoreUtils.nextTick();
await CoreWait.nextTick();
if (!this.loaded) {
return;
}
this.element.style.display = 'inline';
await CoreUtils.nextTick();
await CoreWait.nextTick();
this.element.style.removeProperty('display');
}, 20);

View File

@ -16,7 +16,7 @@ import { ContextLevel } from '@/core/constants';
import { Component, EventEmitter, HostBinding, Input, OnInit, Output } from '@angular/core';
import { CoreAnimations } from '@components/animations';
import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils';
import { CoreText } from '@singletons/text';
import { CoreTextUtils } from '@services/utils/text';
import { CoreUserWithAvatar } from '@components/user-avatar/user-avatar';
@ -102,7 +102,7 @@ export class CoreMessageComponent implements OnInit {
* Copy message to clipboard.
*/
copyMessage(): void {
CoreUtils.copyToClipboard(CoreTextUtils.decodeHTMLEntities(this.text));
CoreText.copyToClipboard(CoreTextUtils.decodeHTMLEntities(this.text));
}
}

View File

@ -28,7 +28,7 @@ import { CoreCourse } from '@features/course/services/course';
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
import { CoreSites } from '@services/sites';
import { CoreTextUtils } from '@services/utils/text';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
const assetsPath = 'assets/img/';
const fallbackModName = 'external-tool';
@ -155,8 +155,8 @@ export class CoreModIconComponent implements OnInit, OnChanges {
}
// If it's an Moodle Theme icon, check if filtericon is set and use it.
if (CoreUrlUtils.isThemeImageUrl(this.iconUrl())) {
const filter = CoreUrlUtils.getThemeImageUrlParam(this.iconUrl(), 'filtericon');
if (CoreUrl.isThemeImageUrl(this.iconUrl())) {
const filter = CoreUrl.getThemeImageUrlParam(this.iconUrl(), 'filtericon');
if (filter === '1') {
this.brandedClass = false;
@ -233,7 +233,7 @@ export class CoreModIconComponent implements OnInit, OnChanges {
* @returns Guessed modname.
*/
protected getComponentNameFromIconUrl(iconUrl: string): string {
const component = CoreUrlUtils.getThemeImageUrlParam(iconUrl, 'component');
const component = CoreUrl.getThemeImageUrlParam(iconUrl, 'component');
// Some invalid components (others may be added later on).
if (component === 'core' || component === 'theme') {

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { CoreSharedModule } from '@/core/shared.module';
import { Component } from '@angular/core';
import { ModalController } from '@singletons';
@ -20,7 +21,11 @@ import { ModalController } from '@singletons';
*/
@Component({
templateUrl: 'refresh-button-modal.html',
styleUrls: ['refresh-button-modal.scss'],
styleUrl: 'refresh-button-modal.scss',
standalone: true,
imports: [
CoreSharedModule,
],
})
export class CoreRefreshButtonModalComponent {

View File

@ -17,7 +17,7 @@ import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular
import { CoreModalComponent } from '@classes/modal-component';
import { CorePromisedValue } from '@classes/promised-value';
import { CoreModals } from '@services/modals';
import { CoreUtils } from '@services/utils/utils';
import { CoreWait } from '@singletons/wait';
import { AngularFrameworkDelegate } from '@singletons';
import { CoreDirectivesRegistry } from '@singletons/directives-registry';
@ -64,13 +64,13 @@ export class CoreSheetModalComponent<T extends CoreModalComponent> implements Af
const wrapper = await this.wrapperElement;
this.content = await AngularFrameworkDelegate.attachViewToDom(wrapper, this.component, this.componentProps ?? {});
await CoreUtils.nextTick();
await CoreWait.nextTick();
this.element.classList.add('active');
this.element.style.zIndex = `${20000 + CoreModals.getTopOverlayIndex()}`;
await CoreUtils.nextTick();
await CoreUtils.wait(300);
await CoreWait.nextTick();
await CoreWait.wait(300);
const instance = CoreDirectivesRegistry.resolve(this.content, this.component);
@ -89,8 +89,8 @@ export class CoreSheetModalComponent<T extends CoreModalComponent> implements Af
this.element.classList.remove('active');
await CoreUtils.nextTick();
await CoreUtils.wait(300);
await CoreWait.nextTick();
await CoreWait.wait(300);
await AngularFrameworkDelegate.removeViewFromDom(wrapper, this.content);
}

View File

@ -20,7 +20,7 @@ import { CoreSwipeSlidesItemsManager } from '@classes/items-management/swipe-sli
import { CorePromisedValue } from '@classes/promised-value';
import { IonContent } from '@ionic/angular';
import { CoreDomUtils, VerticalPoint } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils';
import { CoreWait } from '@singletons/wait';
import { NgZone } from '@singletons';
import { CoreDom } from '@singletons/dom';
import { CoreEventObserver } from '@singletons/events';
@ -230,7 +230,7 @@ export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDe
*/
protected async onItemsUpdated(): Promise<void> {
// Wait for slides to be added in DOM.
await CoreUtils.nextTick();
await CoreWait.nextTick();
// Update the slides component so the slides list reflects the new items.
await this.updateSlidesComponent();
@ -348,7 +348,7 @@ export class CoreSwipeSlidesComponent<Item = unknown> implements OnChanges, OnDe
this.swiper.update();
// We need to ensure the slides are updated before continuing.
await CoreUtils.nextTicks(2);
await CoreWait.nextTicks(2);
}
/**

View File

@ -21,7 +21,7 @@ import { USER_PROFILE_PICTURE_UPDATED, CoreUserBasicData } from '@features/user/
import { CoreNavigator } from '@services/navigator';
import { CoreNetwork } from '@services/network';
import { CoreUserHelper } from '@features/user/services/user-helper';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreSiteInfo } from '@classes/sites/unauthenticated-site';
/**
@ -124,7 +124,7 @@ export class CoreUserAvatarComponent implements OnInit, OnChanges, OnDestroy {
this.fullname = this.fullname || (this.user && (this.user.fullname || this.user.userfullname));
if (this.avatarUrl && CoreUrlUtils.isThemeImageUrl(this.avatarUrl)) {
if (this.avatarUrl && CoreUrl.isThemeImageUrl(this.avatarUrl)) {
this.avatarUrl = undefined;
}

View File

@ -17,6 +17,7 @@ import { Directive, Input, ElementRef, AfterViewInit } from '@angular/core';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils';
import { CoreDom } from '@singletons/dom';
import { CoreWait } from '@singletons/wait';
/**
* Directive to auto focus an element when a view is loaded.
@ -51,7 +52,7 @@ export class CoreAutoFocusDirective implements AfterViewInit {
// Wait in case there is an animation to enter the page, otherwise the interaction
// between the keyboard appearing and the animation causes a visual glitch.
await CoreUtils.wait(540);
await CoreWait.wait(540);
CoreDomUtils.focusElement(this.element);

View File

@ -23,6 +23,7 @@ import { CoreEventObserver } from '@singletons/events';
import { CoreLoadingComponent } from '@components/loading/loading';
import { CoreCancellablePromise } from '@classes/cancellable-promise';
import { CoreDom } from '@singletons/dom';
import { CoreWait } from '@singletons/wait';
/**
* Directive to make an element fixed at the bottom collapsible when scrolling.
@ -101,7 +102,7 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy {
await this.viewportPromise;
this.element.classList.remove('is-active');
await CoreUtils.nextTick();
await CoreWait.nextTick();
// Set a minimum height value.
this.initialHeight = this.element.getBoundingClientRect().height || this.initialHeight;

View File

@ -27,6 +27,7 @@ import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreMath } from '@singletons/math';
import { Subscription } from 'rxjs';
import { CoreFormatTextDirective } from './format-text';
import { CoreWait } from '@singletons/wait';
declare module '@singletons/events' {
@ -344,7 +345,7 @@ export class CoreCollapsibleHeaderDirective implements OnInit, OnChanges, OnDest
await this.visiblePromise;
this.page.classList.remove('collapsible-header-page-is-active');
await CoreUtils.nextTick();
await CoreWait.nextTick();
// Add floating title and measure initial position.
const collapsedHeaderTitle = this.collapsedHeader.querySelector('h1') as HTMLHeadingElement;
@ -429,7 +430,7 @@ export class CoreCollapsibleHeaderDirective implements OnInit, OnChanges, OnDest
}
// Make sure elements have been added to the DOM.
await CoreUtils.nextTick();
await CoreWait.nextTick();
// Wait all loadings and tabs to finish loading.
await CoreDirectivesRegistry.waitMultipleDirectivesReady(this.page, [

View File

@ -26,7 +26,7 @@ import {
import { CoreFile, CoreFileProvider } from '@services/file';
import { CoreFilepool, CoreFilepoolFileActions, CoreFilepoolFileEventData } from '@services/filepool';
import { CoreSites } from '@services/sites';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { CoreLogger } from '@singletons/logger';
import { CoreError } from '@classes/errors/error';
@ -206,8 +206,8 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges, O
const site = await CoreUtils.ignoreErrors(CoreSites.getSite(this.siteId));
const isSiteFile = site?.isSitePluginFileUrl(url);
if (!url || !url.match(/^https?:\/\//i) || CoreUrlUtils.isLocalFileUrl(url) ||
(tagName === 'A' && !(isSiteFile || site?.isSiteThemeImageUrl(url) || CoreUrlUtils.isGravatarUrl(url)))) {
if (!url || !url.match(/^https?:\/\//i) || CoreUrl.isLocalFileUrl(url) ||
(tagName === 'A' && !(isSiteFile || site?.isSiteThemeImageUrl(url) || CoreUrl.isGravatarUrl(url)))) {
this.logger.debug('Ignoring non-downloadable URL: ' + url);
@ -393,7 +393,7 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges, O
finalUrl = CoreFile.convertFileSrc(finalUrl);
}
if (!CoreUrlUtils.isLocalFileUrl(finalUrl) && !finalUrl.includes('#') && tagName !== 'A') {
if (!CoreUrl.isLocalFileUrl(finalUrl) && !finalUrl.includes('#') && tagName !== 'A') {
/* In iOS, if we use the same URL in embedded file and background download then the download only
downloads a few bytes (cached ones). Add an anchor to the URL so both URLs are different.
Don't add this anchor if the URL already has an anchor, otherwise other anchors might not work.

View File

@ -56,6 +56,7 @@ import { FrameElement, FrameElementController } from '@classes/element-controlle
import { CoreUrl } from '@singletons/url';
import { CoreIcons } from '@singletons/icons';
import { ContextLevel } from '../constants';
import { CoreWait } from '@singletons/wait';
/**
* Directive to format text rendered. It renders the HTML and treats all links and media, using CoreLinkDirective
@ -339,7 +340,7 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncDirec
// Show the element again.
this.element.classList.remove('core-loading');
await CoreUtils.nextTick();
await CoreWait.nextTick();
// Emit the afterRender output.
this.afterRender.emit();
@ -380,7 +381,7 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncDirec
this.elementControllers.forEach(controller => controller.destroy());
this.elementControllers = result.elementControllers;
await CoreUtils.nextTick();
await CoreWait.nextTick();
// Add magnifying glasses to images.
this.addImageViewerButton();
@ -705,7 +706,7 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncDirec
const previousDisplay = getComputedStyle(this.element).display;
this.element.style.display = 'inline-block';
await CoreUtils.nextTick();
await CoreWait.nextTick();
width = this.element.getBoundingClientRect().width;

View File

@ -19,7 +19,7 @@ import { IonContent } from '@ionic/angular';
import { CoreFileHelper } from '@services/file-helper';
import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { CoreTextUtils } from '@services/utils/text';
import { CoreConstants } from '@/core/constants';
@ -27,7 +27,6 @@ import { CoreContentLinksHelper } from '@features/contentlinks/services/contentl
import { CoreCustomURLSchemes } from '@services/urlschemes';
import { DomSanitizer } from '@singletons';
import { CoreFilepool } from '@services/filepool';
import { CoreUrl } from '@singletons/url';
import { CoreDom } from '@singletons/dom';
/**
@ -87,7 +86,7 @@ export class CoreLinkDirective implements OnInit {
href = href || this.element.getAttribute('href') || this.element.getAttribute('xlink:href');
if (!href || CoreUrlUtils.getUrlScheme(href) === 'javascript') {
if (!href || CoreUrl.getUrlProtocol(href) === 'javascript') {
return;
}
@ -116,7 +115,7 @@ export class CoreLinkDirective implements OnInit {
*/
protected async navigate(href: string, openIn?: string | null): Promise<void> {
if (CoreUrlUtils.isLocalFileUrl(href)) {
if (CoreUrl.isLocalFileUrl(href)) {
return this.openLocalFile(href);
}

View File

@ -23,6 +23,7 @@ import { CoreCoursesDashboard } from '@features/courses/services/dashboard';
import { CoreTextUtils } from '@services/utils/text';
import { CoreDom } from '@singletons/dom';
import { ContextLevel } from '@/core/constants';
import { CoreWait } from '@singletons/wait';
/**
* Component that displays the list of side blocks.
@ -135,8 +136,8 @@ export class CoreBlockSideBlocksComponent implements OnInit {
const selector = '#block-' + this.initialBlockInstanceId;
await CoreUtils.waitFor(() => !!this.elementRef.nativeElement.querySelector(selector));
await CoreUtils.wait(200);
await CoreWait.waitFor(() => !!this.elementRef.nativeElement.querySelector(selector));
await CoreWait.wait(200);
CoreDom.scrollToElement(this.elementRef.nativeElement, selector, { addYAxis: -10 });
}

View File

@ -85,6 +85,7 @@ import { CorePath } from '@singletons/path';
import { CoreText } from '@singletons/text';
import { CoreTime } from '@singletons/time';
import { CoreUrl } from '@singletons/url';
import { CoreWait } from '@singletons/wait';
import { CoreWindow } from '@singletons/window';
import { CoreCache } from '@classes/cache';
import { CoreDelegate } from '@classes/delegate';
@ -314,6 +315,7 @@ export class CoreCompileProvider {
instance['CoreText'] = CoreText;
instance['CoreTime'] = CoreTime;
instance['CoreUrl'] = CoreUrl;
instance['CoreWait'] = CoreWait;
instance['CoreWindow'] = CoreWindow;
instance['CoreCache'] = CoreCache; // @deprecated since 4.4, plugins should use plain objects instead.
instance['CoreDelegate'] = CoreDelegate;

View File

@ -21,6 +21,7 @@ import { CoreContentLinksHelper } from '../../services/contentlinks-helper';
import { CoreError } from '@classes/errors/error';
import { CoreNavigator } from '@services/navigator';
import { CoreSitesFactory } from '@services/sites-factory';
import { CoreSharedModule } from '@/core/shared.module';
/**
* Page to display the list of sites to choose one to perform a content link action.
@ -28,6 +29,10 @@ import { CoreSitesFactory } from '@services/sites-factory';
@Component({
selector: 'core-content-links-choose-site-modal',
templateUrl: 'choose-site-modal.html',
standalone: true,
imports: [
CoreSharedModule,
],
})
export class CoreContentLinksChooseSiteModalComponent implements OnInit {

View File

@ -1,30 +0,0 @@
// (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 { CoreSharedModule } from '@/core/shared.module';
import { NgModule } from '@angular/core';
import { CoreContentLinksChooseSiteModalComponent } from './choose-site-modal/choose-site-modal';
@NgModule({
declarations: [
CoreContentLinksChooseSiteModalComponent,
],
imports: [
CoreSharedModule,
],
exports: [
CoreContentLinksChooseSiteModalComponent,
],
})
export class CoreContentLinksComponentsModule {}

View File

@ -13,7 +13,6 @@
// limitations under the License.
import { NgModule, Type } from '@angular/core';
import { CoreContentLinksComponentsModule } from './components/components.module';
/**
* Get content links services.
@ -50,8 +49,5 @@ export async function getContentLinksExportedObjects(): Promise<Record<string, u
}
@NgModule({
imports: [
CoreContentLinksComponentsModule,
],
})
export class CoreContentLinksModule {}

View File

@ -15,11 +15,10 @@
import { Injectable } from '@angular/core';
import { CoreLogger } from '@singletons/logger';
import { CoreSites } from '@services/sites';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils';
import { makeSingleton } from '@singletons';
import { CoreText } from '@singletons/text';
import { CoreUrl } from '@singletons/url';
/**
* Interface that all handlers must implement.
@ -174,7 +173,7 @@ export class CoreContentLinksDelegateService {
const linkActions: CoreContentLinksHandlerActions[] = [];
const promises: Promise<void>[] = [];
const params = CoreUrlUtils.extractUrlParams(url);
const params = CoreUrl.extractUrlParams(url);
const relativeUrl = CoreText.addStartingSlash(CoreUrl.toRelativeURL(site.getURL(), url));
for (const name in this.handlers) {

View File

@ -19,7 +19,6 @@ import { CoreContentLinksDelegate, CoreContentLinksAction } from './contentlinks
import { CoreSite } from '@classes/sites/site';
import { makeSingleton, Translate } from '@singletons';
import { CoreNavigator } from '@services/navigator';
import { CoreContentLinksChooseSiteModalComponent } from '../components/choose-site-modal/choose-site-modal';
import { CoreCustomURLSchemes } from '@services/urlschemes';
/**
@ -96,6 +95,9 @@ export class CoreContentLinksHelperProvider {
* @todo set correct root.
*/
async goToChooseSite(url: string): Promise<void> {
const { CoreContentLinksChooseSiteModalComponent }
= await import('@features/contentlinks/components/choose-site-modal/choose-site-modal');
await CoreDomUtils.openModal({
component: CoreContentLinksChooseSiteModalComponent,
componentProps: {

View File

@ -31,7 +31,7 @@ import { CoreCourseHelper, CoreCourseModuleData } from '../services/course-helpe
import { CoreCourseModuleDelegate, CoreCourseModuleMainComponent } from '../services/module-delegate';
import { CoreCourseModulePrefetchDelegate } from '../services/module-prefetch-delegate';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreTime } from '@singletons/time';
/**
@ -506,7 +506,7 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
url = options.url;
} else if (this.pluginName) {
// Use default value.
url = CoreUrlUtils.addParamsToUrl(`/mod/${this.pluginName}/view.php?id=${this.module.id}`, options.data);
url = CoreUrl.addParamsToUrl(`/mod/${this.pluginName}/view.php?id=${this.module.id}`, options.data);
}
}

View File

@ -19,7 +19,6 @@ import { CoreBlockComponentsModule } from '@features/block/components/components
import { CoreCourseFormatComponent } from './course-format/course-format';
import { CoreCourseModuleComponent } from './module/module';
import { CoreCourseModuleCompletionComponent } from './module-completion/module-completion';
import { CoreCourseCourseIndexComponent } from './course-index/course-index';
import { CoreCourseTagAreaComponent } from './tag-area/tag-area';
import { CoreCourseUnsupportedModuleComponent } from './unsupported-module/unsupported-module';
import { CoreCourseModuleCompletionLegacyComponent } from './module-completion-legacy/module-completion-legacy';
@ -37,7 +36,6 @@ import { CoreCourseModuleCompletionDetailsComponent } from './module-completion-
CoreCourseModuleCompletionComponent,
CoreCourseModuleCompletionLegacyComponent,
CoreCourseModuleInfoComponent,
CoreCourseCourseIndexComponent,
CoreCourseCourseIndexTourComponent,
CoreCourseTagAreaComponent,
CoreCourseUnsupportedModuleComponent,
@ -56,7 +54,6 @@ import { CoreCourseModuleCompletionDetailsComponent } from './module-completion-
CoreCourseModuleCompletionComponent,
CoreCourseModuleCompletionLegacyComponent,
CoreCourseModuleInfoComponent,
CoreCourseCourseIndexComponent,
CoreCourseCourseIndexTourComponent,
CoreCourseTagAreaComponent,
CoreCourseUnsupportedModuleComponent,

View File

@ -41,7 +41,7 @@ import { CoreCourseFormatDelegate } from '@features/course/services/format-deleg
import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { IonContent } from '@ionic/angular';
import { CoreUtils } from '@services/utils/utils';
import { CoreCourseCourseIndexComponent, CoreCourseIndexSectionWithModule } from '../course-index/course-index';
import { CoreCourseIndexSectionWithModule } from '../course-index/course-index';
import { CoreBlockHelper } from '@features/block/services/block-helper';
import { CoreNavigator } from '@services/navigator';
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
@ -429,6 +429,8 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
async openCourseIndex(): Promise<void> {
const selectedId = await this.getSelectedSectionId();
const { CoreCourseCourseIndexComponent } = await import('@features/course/components/course-index/course-index');
const data = await CoreDomUtils.openModal<CoreCourseIndexSectionWithModule>({
component: CoreCourseCourseIndexComponent,
initialBreakpoint: 1,

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { CoreSharedModule } from '@/core/shared.module';
import { Component, ElementRef, Input, OnInit } from '@angular/core';
import {
CoreCourse,
@ -23,7 +24,7 @@ import { CoreCourseFormatDelegate } from '@features/course/services/format-deleg
import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
import { CoreCoursesHelper } from '@features/courses/services/courses-helper';
import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils';
import { CoreWait } from '@singletons/wait';
import { ModalController } from '@singletons';
import { CoreDom } from '@singletons/dom';
@ -33,7 +34,11 @@ import { CoreDom } from '@singletons/dom';
@Component({
selector: 'core-course-course-index',
templateUrl: 'course-index.html',
styleUrls: ['course-index.scss'],
styleUrl: 'course-index.scss',
standalone: true,
imports: [
CoreSharedModule,
],
})
export class CoreCourseCourseIndexComponent implements OnInit {
@ -118,11 +123,11 @@ export class CoreCourseCourseIndexComponent implements OnInit {
this.highlighted = CoreCourseFormatDelegate.getSectionHightlightedName(this.course);
// Wait a bit to render the data, otherwise the modal takes a while to appear in big courses or slow devices.
await CoreUtils.wait(400);
await CoreWait.wait(400);
this.loaded = true;
await CoreUtils.nextTick();
await CoreWait.nextTick();
CoreDom.scrollToElement(
this.elementRef.nativeElement,

View File

@ -42,6 +42,7 @@ import { CoreNavigator } from '@services/navigator';
import { CoreRefreshContext, CORE_REFRESH_CONTEXT } from '@/core/utils/refresh-context';
import { CoreCoursesHelper } from '@features/courses/services/courses-helper';
import { CoreSites } from '@services/sites';
import { CoreWait } from '@singletons/wait';
/**
* Page that displays the contents of a course.
@ -411,7 +412,7 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy, CoreRefreshCon
this.changeDetectorRef.detectChanges();
if (scrollTop > 0) {
await CoreUtils.nextTick();
await CoreWait.nextTick();
this.content?.scrollToPoint(0, scrollTop, 0);
}
}

View File

@ -30,6 +30,7 @@ import { CoreCoursesHelper, CoreCourseWithImageAndColor } from '@features/course
import { CoreColors } from '@singletons/colors';
import { CorePath } from '@singletons/path';
import { CoreSites } from '@services/sites';
import { CoreWait } from '@singletons/wait';
/**
* Page that displays the list of courses the user is enrolled in.
@ -209,7 +210,7 @@ export class CoreCourseIndexPage implements OnInit, OnDestroy {
// Select the tab if needed.
this.firstTabName = undefined;
if (tabToLoad) {
await CoreUtils.nextTick();
await CoreWait.nextTick();
this.tabsComponent?.selectByIndex(tabToLoad);
}

View File

@ -59,7 +59,7 @@ import { CoreFileHelper } from '@services/file-helper';
import { CoreNetwork } from '@services/network';
import { CoreSite } from '@classes/sites/site';
import { CoreFile } from '@services/file';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUrl } from '@singletons/url';
import { CoreTextUtils } from '@services/utils/text';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreFilterHelper } from '@features/filter/services/filter-helper';
@ -710,7 +710,7 @@ export class CoreCourseHelperProvider {
options,
);
if (CoreUrlUtils.isLocalFileUrl(result.path)) {
if (CoreUrl.isLocalFileUrl(result.path)) {
return CoreUtils.openFile(result.path, options);
}

View File

@ -31,6 +31,7 @@ import { CoreCourses } from '../../services/courses';
import { CoreTime } from '@singletons/time';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { Translate } from '@singletons';
import { CoreWait } from '@singletons/wait';
/**
* Page that shows a my courses.
@ -129,7 +130,7 @@ export class CoreCoursesMyPage implements OnInit, OnDestroy, AsyncDirective {
this.loadedBlock = blocks.mainBlocks.concat(blocks.sideBlocks).find((block) => block.name == 'myoverview');
this.hasSideBlocks = supportsMyParam && CoreBlockDelegate.hasSupportedBlock(blocks.sideBlocks);
await CoreUtils.nextTicks(2);
await CoreWait.nextTicks(2);
this.myOverviewBlock = this.block?.dynamicComponent?.instance as AddonBlockMyOverviewComponent;

View File

@ -1,33 +0,0 @@
// (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 { CoreDataPrivacyContactDPOComponent } from './contactdpo/contactdpo';
import { CoreDataPrivacyNewRequestComponent } from './newrequest/newrequest';
@NgModule({
declarations: [
CoreDataPrivacyContactDPOComponent,
CoreDataPrivacyNewRequestComponent,
],
imports: [
CoreSharedModule,
],
exports: [
CoreDataPrivacyContactDPOComponent,
CoreDataPrivacyNewRequestComponent,
],
})
export class CoreDataPrivacyComponentsModule {}

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { CoreSharedModule } from '@/core/shared.module';
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { CoreDataPrivacy } from '@features/dataprivacy/services/dataprivacy';
@ -28,6 +29,11 @@ import { ModalController } from '@singletons';
@Component({
selector: 'core-data-privacy-contact-dpo',
templateUrl: 'contactdpo.html',
standalone: true,
imports: [
CoreSharedModule,
],
})
export class CoreDataPrivacyContactDPOComponent implements OnInit {

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { CoreSharedModule } from '@/core/shared.module';
import { Component, Input, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import {
@ -29,6 +30,10 @@ import { ModalController } from '@singletons';
@Component({
selector: 'core-data-privacy-new-request',
templateUrl: 'newrequest.html',
standalone: true,
imports: [
CoreSharedModule,
],
})
export class CoreDataPrivacyNewRequestComponent implements OnInit {

View File

@ -17,7 +17,6 @@ import { CoreUserDelegate } from '@features/user/services/user-delegate';
import { CoreDataPrivacyUserHandler } from './services/handlers/user';
import { Routes } from '@angular/router';
import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-routing.module';
import { CoreDataPrivacyComponentsModule } from './components/components.module';
import { CORE_DATAPRIVACY_PAGE_NAME } from './constants';
import { CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreDataPrivacyDataRequestsLinkHandler } from './services/handlers/datarequests-link';
@ -33,7 +32,6 @@ const routes: Routes = [
@NgModule({
imports: [
CoreMainMenuTabRoutingModule.forChild(routes),
CoreDataPrivacyComponentsModule,
],
providers: [
{

View File

@ -13,8 +13,6 @@
// limitations under the License.
import { Component, OnInit } from '@angular/core';
import { CoreDataPrivacyContactDPOComponent } from '@features/dataprivacy/components/contactdpo/contactdpo';
import { CoreDataPrivacyNewRequestComponent } from '@features/dataprivacy/components/newrequest/newrequest';
import {
CoreDataPrivacy,
CoreDataPrivacyDataRequestType,
@ -115,6 +113,9 @@ export class CoreDataPrivacyMainPage implements OnInit {
* Open the contact DPO modal.
*/
async contactDPO(): Promise<void> {
const { CoreDataPrivacyContactDPOComponent } =
await import('@features/dataprivacy/components/contactdpo/contactdpo');
// Create and show the modal.
const succeed = await CoreDomUtils.openModal<boolean>({
component: CoreDataPrivacyContactDPOComponent,
@ -134,6 +135,9 @@ export class CoreDataPrivacyMainPage implements OnInit {
* Open the new request modal.
*/
async newRequest(createType?: CoreDataPrivacyDataRequestType): Promise<void> {
const { CoreDataPrivacyNewRequestComponent } =
await import('@features/dataprivacy/components/newrequest/newrequest');
// Create and show the modal.
const succeed = await CoreDomUtils.openModal<boolean>({
component: CoreDataPrivacyNewRequestComponent,

Some files were not shown because too many files have changed in this diff Show More