diff --git a/src/addons/badges/pages/issued-badge/issued-badge.html b/src/addons/badges/pages/issued-badge/issued-badge.html
index 5f06dc1d6..9686be66d 100644
--- a/src/addons/badges/pages/issued-badge/issued-badge.html
+++ b/src/addons/badges/pages/issued-badge/issued-badge.html
@@ -49,7 +49,7 @@
{{ 'addon.badges.contact' | translate}}
-
+
{{ badge.issuercontact }}
@@ -95,7 +95,7 @@
{{ 'addon.badges.imageauthoremail' | translate}}
-
+
{{ badge.imageauthoremail }}
@@ -103,7 +103,7 @@
{{ 'addon.badges.imageauthorurl' | translate}}
- {{ badge.imageauthorurl }}
+ {{ badge.imageauthorurl }}
@@ -166,7 +166,7 @@
{{ 'addon.badges.issueremail' | translate}}
-
+
{{ badge.endorsement.issueremail }}
@@ -175,7 +175,7 @@
{{ 'addon.badges.issuerurl' | translate}}
- {{ badge.endorsement.issuerurl }}
+ {{ badge.endorsement.issuerurl }}
@@ -187,7 +187,7 @@
{{ 'addon.badges.claimid' | translate}}
- {{ badge.endorsement.claimid }}
+ {{ badge.endorsement.claimid }}
@@ -225,7 +225,7 @@
+ [autoLogin]="false">
{{ alignment.targetname }}
diff --git a/src/addons/block/timeline/components/events/events.ts b/src/addons/block/timeline/components/events/events.ts
index 041c22755..bb69312bc 100644
--- a/src/addons/block/timeline/components/events/events.ts
+++ b/src/addons/block/timeline/components/events/events.ts
@@ -19,6 +19,7 @@ import { CoreTextUtils } from '@services/utils/text';
import { CoreEnrolledCourseDataWithOptions } from '@features/courses/services/courses-helper';
import { AddonBlockTimelineDayEvents } from '@addons/block/timeline/classes/section';
import { CoreSharedModule } from '@/core/shared.module';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Directive to render a list of events in course overview.
@@ -36,9 +37,9 @@ export class AddonBlockTimelineEventsComponent implements OnInit {
@Input() events: AddonBlockTimelineDayEvents[] = []; // The events to render.
@Input() course?: CoreEnrolledCourseDataWithOptions; // Whether to show the course name.
- @Input() showInlineCourse = true; // Whether to show the course name within event items.
- @Input() canLoadMore = false; // Whether more events can be loaded.
- @Input() loadingMore = false; // Whether loading is ongoing.
+ @Input({ transform: toBoolean }) showInlineCourse = true; // Whether to show the course name within event items.
+ @Input({ transform: toBoolean }) canLoadMore = false; // Whether more events can be loaded.
+ @Input({ transform: toBoolean }) loadingMore = false; // Whether loading is ongoing.
@Output() loadMore = new EventEmitter(); // Notify that more events should be loaded.
colorizeIcons = false;
diff --git a/src/addons/calendar/components/calendar/calendar.ts b/src/addons/calendar/components/calendar/calendar.ts
index e2df77771..2920b3851 100644
--- a/src/addons/calendar/components/calendar/calendar.ts
+++ b/src/addons/calendar/components/calendar/calendar.ts
@@ -53,6 +53,7 @@ import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { CoreUrl } from '@singletons/url';
import { CoreTime } from '@singletons/time';
import { Translate } from '@singletons';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component that displays a calendar.
@@ -69,9 +70,9 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
@Input() initialYear?: number; // Initial year to load.
@Input() initialMonth?: number; // Initial month to load.
@Input() filter?: AddonCalendarFilter; // Filter to apply.
- @Input() hidden?: boolean; // Whether the component is hidden.
- @Input() canNavigate?: string | boolean; // Whether to include arrows to change the month. Defaults to true.
- @Input() displayNavButtons?: string | boolean; // Whether to display nav buttons created by this component. Defaults to true.
+ @Input({ transform: toBoolean }) hidden = false; // Whether the component is hidden.
+ @Input({ transform: toBoolean }) canNavigate = true; // Whether to include arrows to change the month
+ @Input({ transform: toBoolean }) displayNavButtons = true; // Whether to display nav buttons created by this component.
@Output() onEventClicked = new EventEmitter();
@Output() onDayClicked = new EventEmitter<{day: number; month: number; year: number}>();
@@ -145,10 +146,6 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
* @inheritdoc
*/
ngOnInit(): void {
- this.canNavigate = typeof this.canNavigate == 'undefined' ? true : CoreUtils.isTrueOrOne(this.canNavigate);
- this.displayNavButtons = typeof this.displayNavButtons == 'undefined' ? true :
- CoreUtils.isTrueOrOne(this.displayNavButtons);
-
const source = new AddonCalendarMonthSlidesItemsManagerSource(this, moment({
year: this.initialYear,
month: this.initialMonth ? this.initialMonth - 1 : undefined,
diff --git a/src/addons/calendar/pages/event/event.html b/src/addons/calendar/pages/event/event.html
index 6f21e79ef..b7f1ff8e4 100644
--- a/src/addons/calendar/pages/event/event.html
+++ b/src/addons/calendar/pages/event/event.html
@@ -104,7 +104,7 @@
{{ 'core.location' | translate}}
-
+
diff --git a/src/addons/mod/assign/classes/base-feedback-plugin-component.ts b/src/addons/mod/assign/classes/base-feedback-plugin-component.ts
index 31713b758..fd740ca95 100644
--- a/src/addons/mod/assign/classes/base-feedback-plugin-component.ts
+++ b/src/addons/mod/assign/classes/base-feedback-plugin-component.ts
@@ -18,6 +18,7 @@ import { CoreError } from '@classes/errors/error';
import { CoreModals } from '@services/modals';
import { AddonModAssignFeedbackCommentsTextData } from '../feedback/comments/services/handler';
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../services/assign';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Base class for component to render a feedback plugin.
@@ -27,13 +28,13 @@ import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission }
})
export class AddonModAssignFeedbackPluginBaseComponent implements IAddonModAssignFeedbackPluginComponent {
- @Input() assign!: AddonModAssignAssign; // The assignment.
- @Input() submission!: AddonModAssignSubmission; // The submission.
- @Input() plugin!: AddonModAssignPlugin; // The plugin object.
- @Input() userId!: number; // The user ID of the submission.
+ @Input({ required: true }) assign!: AddonModAssignAssign; // The assignment.
+ @Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
+ @Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
+ @Input({ required: true }) userId!: number; // The user ID of the submission.
@Input() configs?: Record; // The configs for the plugin.
- @Input() canEdit = false; // Whether the user can edit.
- @Input() edit = false; // Whether the user is editing.
+ @Input({ transform: toBoolean }) canEdit = false; // Whether the user can edit.
+ @Input({ transform: toBoolean }) edit = false; // Whether the user is editing.
/**
* Open a modal to edit the feedback plugin.
diff --git a/src/addons/mod/assign/classes/base-submission-plugin-component.ts b/src/addons/mod/assign/classes/base-submission-plugin-component.ts
index 56f938d0b..f245c0a98 100644
--- a/src/addons/mod/assign/classes/base-submission-plugin-component.ts
+++ b/src/addons/mod/assign/classes/base-submission-plugin-component.ts
@@ -14,6 +14,7 @@
import { Component, Input } from '@angular/core';
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../services/assign';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Base class for component to render a submission plugin.
@@ -23,12 +24,12 @@ import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission }
})
export class AddonModAssignSubmissionPluginBaseComponent {
- @Input() assign!: AddonModAssignAssign; // The assignment.
- @Input() submission!: AddonModAssignSubmission; // The submission.
- @Input() plugin!: AddonModAssignPlugin; // The plugin object.
+ @Input({ required: true }) assign!: AddonModAssignAssign; // The assignment.
+ @Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
+ @Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
@Input() configs?: Record; // The configs for the plugin.
- @Input() edit = false; // Whether the user is editing.
- @Input() allowOffline = false; // Whether to allow offline.
+ @Input({ transform: toBoolean }) edit = false; // Whether the user is editing.
+ @Input({ transform: toBoolean }) allowOffline = false; // Whether to allow offline.
/**
* Invalidate the data.
diff --git a/src/addons/mod/assign/components/edit-feedback-modal/edit-feedback-modal.ts b/src/addons/mod/assign/components/edit-feedback-modal/edit-feedback-modal.ts
index 35682d76f..aafd35365 100644
--- a/src/addons/mod/assign/components/edit-feedback-modal/edit-feedback-modal.ts
+++ b/src/addons/mod/assign/components/edit-feedback-modal/edit-feedback-modal.ts
@@ -37,10 +37,10 @@ import { AddonModAssignComponentsModule } from '../components.module';
})
export class AddonModAssignEditFeedbackModalComponent {
- @Input() assign!: AddonModAssignAssign; // The assignment.
- @Input() submission!: AddonModAssignSubmission; // The submission.
- @Input() plugin!: AddonModAssignPlugin; // The plugin object.
- @Input() userId!: number; // The user ID of the submission.
+ @Input({ required: true }) assign!: AddonModAssignAssign; // The assignment.
+ @Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
+ @Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
+ @Input({ required: true }) userId!: number; // The user ID of the submission.
@ViewChild('editFeedbackForm') formElement?: ElementRef;
diff --git a/src/addons/mod/assign/components/feedback-plugin/feedback-plugin.ts b/src/addons/mod/assign/components/feedback-plugin/feedback-plugin.ts
index 136e991b5..0d3fd81a5 100644
--- a/src/addons/mod/assign/components/feedback-plugin/feedback-plugin.ts
+++ b/src/addons/mod/assign/components/feedback-plugin/feedback-plugin.ts
@@ -25,6 +25,7 @@ import {
import { AddonModAssignHelper, AddonModAssignPluginConfig } from '../../services/assign-helper';
import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate';
import { ADDON_MOD_ASSIGN_COMPONENT } from '../../constants';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component that displays an assignment feedback plugin.
@@ -37,12 +38,12 @@ export class AddonModAssignFeedbackPluginComponent implements OnInit {
@ViewChild(CoreDynamicComponent) dynamicComponent!: CoreDynamicComponent;
- @Input() assign!: AddonModAssignAssign; // The assignment.
- @Input() submission!: AddonModAssignSubmission; // The submission.
- @Input() plugin!: AddonModAssignPlugin; // The plugin object.
- @Input() userId!: number; // The user ID of the submission.
- @Input() canEdit = false; // Whether the user can edit.
- @Input() edit = false; // Whether the user is editing.
+ @Input({ required: true }) assign!: AddonModAssignAssign; // The assignment.
+ @Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
+ @Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
+ @Input({ required: true }) userId!: number; // The user ID of the submission.
+ @Input({ transform: toBoolean }) canEdit = false; // Whether the user can edit.
+ @Input({ transform: toBoolean }) edit = false; // Whether the user is editing.
pluginComponent?: Type; // Component to render the plugin.
data?: AddonModAssignFeedbackPluginData; // Data to pass to the component.
diff --git a/src/addons/mod/assign/components/submission-plugin/submission-plugin.ts b/src/addons/mod/assign/components/submission-plugin/submission-plugin.ts
index 93210b120..4010a9193 100644
--- a/src/addons/mod/assign/components/submission-plugin/submission-plugin.ts
+++ b/src/addons/mod/assign/components/submission-plugin/submission-plugin.ts
@@ -25,6 +25,7 @@ import { AddonModAssignSubmissionDelegate } from '../../services/submission-dele
import { CoreFileEntry } from '@services/file-helper';
import type { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
import { ADDON_MOD_ASSIGN_COMPONENT } from '../../constants';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component that displays an assignment submission plugin.
@@ -37,11 +38,11 @@ export class AddonModAssignSubmissionPluginComponent implements OnInit {
@ViewChild(CoreDynamicComponent) dynamicComponent!: CoreDynamicComponent;
- @Input() assign!: AddonModAssignAssign; // The assignment.
- @Input() submission!: AddonModAssignSubmission; // The submission.
- @Input() plugin!: AddonModAssignPlugin; // The plugin object.
- @Input() edit = false; // Whether the user is editing.
- @Input() allowOffline = false; // Whether to allow offline.
+ @Input({ required: true }) assign!: AddonModAssignAssign; // The assignment.
+ @Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
+ @Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
+ @Input({ transform: toBoolean }) edit = false; // Whether the user is editing.
+ @Input({ transform: toBoolean }) allowOffline = false; // Whether to allow offline.
pluginComponent?: Type; // Component to render the plugin.
data?: AddonModAssignSubmissionPluginData; // Data to pass to the component.
diff --git a/src/addons/mod/assign/components/submission/submission.ts b/src/addons/mod/assign/components/submission/submission.ts
index 420b69701..5d4148030 100644
--- a/src/addons/mod/assign/components/submission/submission.ts
+++ b/src/addons/mod/assign/components/submission/submission.ts
@@ -82,9 +82,9 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
@ViewChildren(AddonModAssignSubmissionPluginComponent) submissionComponents!:
QueryList;
- @Input() courseId!: number; // Course ID the submission belongs to.
- @Input() moduleId!: number; // Module ID the submission belongs to.
- @Input() submitId!: number; // User that did the submission.
+ @Input({ required: true }) courseId!: number; // Course ID the submission belongs to.
+ @Input({ required: true }) moduleId!: number; // Module ID the submission belongs to.
+ @Input() submitId!: number; // User that did the submission. Defaults to current user
@Input() blindId?: number; // Blinded user ID (if it's blinded).
loaded = false; // Whether data has been loaded.
diff --git a/src/addons/mod/chat/components/users-modal/users-modal.ts b/src/addons/mod/chat/components/users-modal/users-modal.ts
index 1ebd510e7..6f40a45fd 100644
--- a/src/addons/mod/chat/components/users-modal/users-modal.ts
+++ b/src/addons/mod/chat/components/users-modal/users-modal.ts
@@ -33,8 +33,8 @@ import { CoreSharedModule } from '@/core/shared.module';
})
export class AddonModChatUsersModalComponent implements OnInit, OnDestroy {
- @Input() sessionId!: string;
- @Input() cmId!: number;
+ @Input({ required: true }) sessionId!: string;
+ @Input({ required: true }) cmId!: number;
users: AddonModChatUser[] = [];
usersLoaded = false;
diff --git a/src/addons/mod/data/classes/base-field-plugin-component.ts b/src/addons/mod/data/classes/base-field-plugin-component.ts
index 93483a028..72a64b03c 100644
--- a/src/addons/mod/data/classes/base-field-plugin-component.ts
+++ b/src/addons/mod/data/classes/base-field-plugin-component.ts
@@ -26,8 +26,8 @@ import { AddonModDataTemplateMode } from '../constants';
})
export abstract class AddonModDataFieldPluginBaseComponent implements OnInit, OnChanges {
- @Input() mode!: AddonModDataTemplateMode; // The render mode.
- @Input() field!: AddonModDataField; // The field to render.
+ @Input({ required: true }) mode!: AddonModDataTemplateMode; // The render mode.
+ @Input({ required: true }) field!: AddonModDataField; // The field to render.
@Input() value?: Partial; // The value of the field.
@Input() database?: AddonModDataData; // Database object.
@Input() error?: string; // Error when editing.
diff --git a/src/addons/mod/data/components/action/action.ts b/src/addons/mod/data/components/action/action.ts
index 10022f9f8..57a9da66d 100644
--- a/src/addons/mod/data/components/action/action.ts
+++ b/src/addons/mod/data/components/action/action.ts
@@ -45,10 +45,10 @@ import {
export class AddonModDataActionComponent implements OnInit {
@Input() access?: AddonModDataGetDataAccessInformationWSResponse; // Access info.
- @Input() mode!: AddonModDataTemplateMode; // The render mode.
- @Input() action!: AddonModDataAction; // The field to render.
- @Input() entry!: AddonModDataEntry; // The value of the field.
- @Input() database!: AddonModDataData; // Database object.
+ @Input({ required: true }) mode!: AddonModDataTemplateMode; // The render mode.
+ @Input({ required: true }) action!: AddonModDataAction; // The field to render.
+ @Input({ required: true }) entry!: AddonModDataEntry; // The value of the field.
+ @Input({ required: true }) database!: AddonModDataData; // Database object.
@Input() title = ''; // Name of the module.
@Input() group = 0; // Module group.
@Input() offset?: number; // Offset of the entry.
diff --git a/src/addons/mod/data/components/field-plugin/field-plugin.ts b/src/addons/mod/data/components/field-plugin/field-plugin.ts
index 3527ccee3..f364c1a67 100644
--- a/src/addons/mod/data/components/field-plugin/field-plugin.ts
+++ b/src/addons/mod/data/components/field-plugin/field-plugin.ts
@@ -32,8 +32,8 @@ export class AddonModDataFieldPluginComponent implements OnInit, OnChanges {
@ViewChild(CoreDynamicComponent) dynamicComponent?: CoreDynamicComponent;
- @Input() mode!: AddonModDataTemplateMode; // The render mode.
- @Input() field!: AddonModDataField; // The field to render.
+ @Input({ required: true }) mode!: AddonModDataTemplateMode; // The render mode.
+ @Input({ required: true }) field!: AddonModDataField; // The field to render.
@Input() value?: unknown; // The value of the field.
@Input() database?: AddonModDataData; // Database object.
@Input() error?: string; // Error when editing.
diff --git a/src/addons/mod/data/components/search-modal/search-modal.ts b/src/addons/mod/data/components/search-modal/search-modal.ts
index 2867c9fea..9f7cf1086 100644
--- a/src/addons/mod/data/components/search-modal/search-modal.ts
+++ b/src/addons/mod/data/components/search-modal/search-modal.ts
@@ -50,9 +50,9 @@ export class AddonModDataSearchModalComponent implements OnInit {
@ViewChild('searchFormEl') formElement!: ElementRef;
- @Input() search!: AddonModDataSearchDataParams;
- @Input() fields!: Record;
- @Input() database!: AddonModDataData;
+ @Input({ required: true }) search!: AddonModDataSearchDataParams;
+ @Input({ required: true }) fields!: Record;
+ @Input({ required: true }) database!: AddonModDataData;
advancedSearch = '';
advancedIndexed: CoreFormFields = {};
diff --git a/src/addons/mod/forum/components/discussion-options-menu/discussion-options-menu.ts b/src/addons/mod/forum/components/discussion-options-menu/discussion-options-menu.ts
index 0eb646d2d..91e3041fa 100644
--- a/src/addons/mod/forum/components/discussion-options-menu/discussion-options-menu.ts
+++ b/src/addons/mod/forum/components/discussion-options-menu/discussion-options-menu.ts
@@ -30,9 +30,9 @@ import { CoreToasts } from '@services/toasts';
})
export class AddonModForumDiscussionOptionsMenuComponent implements OnInit {
- @Input() discussion!: AddonModForumDiscussion; // The discussion.
- @Input() forumId!: number; // The forum Id.
- @Input() cmId!: number; // The component module Id.
+ @Input({ required: true }) discussion!: AddonModForumDiscussion; // The discussion.
+ @Input({ required: true }) forumId!: number; // The forum Id.
+ @Input({ required: true }) cmId!: number; // The component module Id.
canPin = false;
diff --git a/src/addons/mod/forum/components/post-options-menu/post-options-menu.ts b/src/addons/mod/forum/components/post-options-menu/post-options-menu.ts
index 8dccdcb02..e7f44e28b 100644
--- a/src/addons/mod/forum/components/post-options-menu/post-options-menu.ts
+++ b/src/addons/mod/forum/components/post-options-menu/post-options-menu.ts
@@ -30,9 +30,9 @@ import { CoreNetworkError } from '@classes/errors/network-error';
})
export class AddonModForumPostOptionsMenuComponent implements OnInit {
- @Input() post!: AddonModForumPost; // The post.
- @Input() cmId!: number;
- @Input() forumId!: number; // The forum Id.
+ @Input({ required: true }) post!: AddonModForumPost; // The post.
+ @Input({ required: true }) cmId!: number;
+ @Input({ required: true }) forumId!: number; // The forum Id.
canEdit = false;
canDelete = false;
diff --git a/src/addons/mod/forum/components/post/post.ts b/src/addons/mod/forum/components/post/post.ts
index 759782675..0662f5a32 100644
--- a/src/addons/mod/forum/components/post/post.ts
+++ b/src/addons/mod/forum/components/post/post.ts
@@ -54,6 +54,7 @@ import { CoreDom } from '@singletons/dom';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { ADDON_MOD_FORUM_CHANGE_DISCUSSION_EVENT, ADDON_MOD_FORUM_COMPONENT } from '../../constants';
import { CoreToasts } from '@services/toasts';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Components that shows a discussion post, its attachments and the action buttons allowed (reply, etc.).
@@ -65,21 +66,21 @@ import { CoreToasts } from '@services/toasts';
})
export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges {
- @Input() post!: AddonModForumPost; // Post.
- @Input() courseId!: number; // Post's course ID.
- @Input() discussionId!: number; // Post's' discussion ID.
+ @Input({ required: true }) post!: AddonModForumPost; // Post.
+ @Input({ required: true }) courseId!: number; // Post's course ID.
+ @Input({ required: true }) discussionId!: number; // Post's' discussion ID.
@Input() discussion?: AddonModForumDiscussion; // Post's' discussion, only for starting posts.
- @Input() component!: string; // Component this post belong to.
- @Input() componentId!: number; // Component ID.
- @Input() formData!: AddonModForumSharedPostFormData; // Object with the new post data. Usually shared between posts.
- @Input() originalData!: Omit; // Original post data. Usually shared between posts.
- @Input() trackPosts!: boolean; // True if post is being tracked.
- @Input() forum!: AddonModForumData; // The forum the post belongs to. Required for attachments and offline posts.
- @Input() accessInfo!: AddonModForumAccessInformation; // Forum access information.
+ @Input({ required: true }) component!: string; // Component this post belong to.
+ @Input({ required: true }) componentId!: number; // Component ID.
+ @Input({ required: true }) formData!: AddonModForumSharedPostFormData; // New post data. Usually shared between posts.
+ @Input({ required: true }) originalData!: Omit; // Original data. Usually shared between posts.
+ @Input({ required: true, transform: toBoolean }) trackPosts = false; // True if post is being tracked.
+ @Input({ required: true }) forum!: AddonModForumData; // The forum the post belongs to.
+ @Input({ required: true }) accessInfo!: AddonModForumAccessInformation; // Forum access information.
@Input() parentSubject?: string; // Subject of parent post.
@Input() ratingInfo?: CoreRatingInfo; // Rating info item.
- @Input() leavingPage?: boolean; // Whether the page that contains this post is being left and will be destroyed.
- @Input() highlight = false;
+ @Input({ transform: toBoolean }) leavingPage = false; // Whether the page that contains this post is being left.
+ @Input({ transform: toBoolean }) highlight = false;
@Output() onPostChange: EventEmitter = new EventEmitter(); // Event emitted when a reply is posted or modified.
@ViewChild('replyFormEl') formElement!: ElementRef;
diff --git a/src/addons/mod/quiz/accessrules/offlineattempts/component/offlineattempts.ts b/src/addons/mod/quiz/accessrules/offlineattempts/component/offlineattempts.ts
index ea9238e3e..bcf26e137 100644
--- a/src/addons/mod/quiz/accessrules/offlineattempts/component/offlineattempts.ts
+++ b/src/addons/mod/quiz/accessrules/offlineattempts/component/offlineattempts.ts
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { toBoolean } from '@/core/transforms/boolean';
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
import { AddonModQuizSync } from '@addons/mod/quiz/services/quiz-sync';
import { Component, OnInit, Input } from '@angular/core';
@@ -29,7 +30,7 @@ export class AddonModQuizAccessOfflineAttemptsComponent implements OnInit {
@Input() rule?: string; // The name of the rule.
@Input() quiz?: AddonModQuizQuizWSData; // The quiz the rule belongs to.
@Input() attempt?: AddonModQuizAttemptWSData; // The attempt being started/continued.
- @Input() prefetch?: boolean; // Whether the user is prefetching the quiz.
+ @Input({ transform: toBoolean }) prefetch = false; // Whether the user is prefetching the quiz.
@Input() siteId?: string; // Site ID.
@Input() form?: FormGroup; // Form where to add the form control.
diff --git a/src/addons/mod/quiz/accessrules/password/component/password.ts b/src/addons/mod/quiz/accessrules/password/component/password.ts
index 77ce32ac5..65e3215dc 100644
--- a/src/addons/mod/quiz/accessrules/password/component/password.ts
+++ b/src/addons/mod/quiz/accessrules/password/component/password.ts
@@ -16,6 +16,7 @@ import { Component, OnInit, Input } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component to render the preflight for password.
@@ -29,7 +30,7 @@ export class AddonModQuizAccessPasswordComponent implements OnInit {
@Input() rule?: string; // The name of the rule.
@Input() quiz?: AddonModQuizQuizWSData; // The quiz the rule belongs to.
@Input() attempt?: AddonModQuizAttemptWSData; // The attempt being started/continued.
- @Input() prefetch?: boolean; // Whether the user is prefetching the quiz.
+ @Input({ transform: toBoolean }) prefetch = false; // Whether the user is prefetching the quiz.
@Input() siteId?: string; // Site ID.
@Input() form?: FormGroup; // Form where to add the form control.
diff --git a/src/addons/mod/quiz/accessrules/timelimit/component/timelimit.ts b/src/addons/mod/quiz/accessrules/timelimit/component/timelimit.ts
index b66ae5b3c..b702e889a 100644
--- a/src/addons/mod/quiz/accessrules/timelimit/component/timelimit.ts
+++ b/src/addons/mod/quiz/accessrules/timelimit/component/timelimit.ts
@@ -17,6 +17,7 @@ import { FormGroup } from '@angular/forms';
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
import { CoreTime } from '@singletons/time';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component to render the preflight for time limit.
@@ -30,7 +31,7 @@ export class AddonModQuizAccessTimeLimitComponent implements OnInit {
@Input() rule?: string; // The name of the rule.
@Input() quiz?: AddonModQuizQuizWSData; // The quiz the rule belongs to.
@Input() attempt?: AddonModQuizAttemptWSData; // The attempt being started/continued.
- @Input() prefetch?: boolean; // Whether the user is prefetching the quiz.
+ @Input({ transform: toBoolean }) prefetch = false; // Whether the user is prefetching the quiz.
@Input() siteId?: string; // Site ID.
@Input() form?: FormGroup; // Form where to add the form control.
diff --git a/src/addons/mod/quiz/components/attempt-info/attempt-info.ts b/src/addons/mod/quiz/components/attempt-info/attempt-info.ts
index 25c0498ac..4e6ef30c6 100644
--- a/src/addons/mod/quiz/components/attempt-info/attempt-info.ts
+++ b/src/addons/mod/quiz/components/attempt-info/attempt-info.ts
@@ -30,8 +30,8 @@ import { isSafeNumber } from '@/core/utils/types';
})
export class AddonModQuizAttemptInfoComponent implements OnChanges {
- @Input() quiz!: AddonModQuizQuizData;
- @Input() attempt!: AddonModQuizAttempt;
+ @Input({ required: true }) quiz!: AddonModQuizQuizData;
+ @Input({ required: true }) attempt!: AddonModQuizAttempt;
@Input() additionalData?: AddonModQuizWSAdditionalData[]; // Additional data to display for the attempt.
isFinished = false;
diff --git a/src/addons/mod/quiz/components/attempt-state/attempt-state.ts b/src/addons/mod/quiz/components/attempt-state/attempt-state.ts
index dd165198a..11bae29df 100644
--- a/src/addons/mod/quiz/components/attempt-state/attempt-state.ts
+++ b/src/addons/mod/quiz/components/attempt-state/attempt-state.ts
@@ -14,6 +14,7 @@
import { Component, Input, OnChanges } from '@angular/core';
import { AddonModQuiz } from '../../services/quiz';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component that displays an attempt state.
@@ -26,7 +27,7 @@ import { AddonModQuiz } from '../../services/quiz';
export class AddonModQuizAttemptStateComponent implements OnChanges {
@Input() state = '';
- @Input() finishedOffline = false;
+ @Input({ transform: toBoolean }) finishedOffline = false;
readableState = '';
color = '';
diff --git a/src/addons/mod/quiz/components/navigation-modal/navigation-modal.ts b/src/addons/mod/quiz/components/navigation-modal/navigation-modal.ts
index 1b71ea075..5950c7b04 100644
--- a/src/addons/mod/quiz/components/navigation-modal/navigation-modal.ts
+++ b/src/addons/mod/quiz/components/navigation-modal/navigation-modal.ts
@@ -13,6 +13,7 @@
// limitations under the License.
import { CoreSharedModule } from '@/core/shared.module';
+import { toBoolean } from '@/core/transforms/boolean';
import { Component, Input } from '@angular/core';
import { CoreQuestionQuestionParsed } from '@features/question/services/question';
@@ -32,11 +33,11 @@ import { ModalController } from '@singletons';
export class AddonModQuizNavigationModalComponent {
@Input() navigation?: AddonModQuizNavigationQuestion[]; // Whether the user is reviewing the attempt.
- @Input() summaryShown?: boolean; // Whether summary is currently being shown.
+ @Input({ transform: toBoolean }) summaryShown = false; // Whether summary is currently being shown.
@Input() nextPage?: number; // Next page.
@Input() currentPage?: number; // Current page.
- @Input() isReview?: boolean; // Whether the user is reviewing the attempt.
- @Input() isSequential?: boolean; // Whether quiz navigation is sequential.
+ @Input({ transform: toBoolean }) isReview = false; // Whether the user is reviewing the attempt.
+ @Input({ transform: toBoolean }) isSequential = false; // Whether quiz navigation is sequential.
/**
* Close modal.
diff --git a/src/addons/mod/quiz/components/preflight-modal/preflight-modal.ts b/src/addons/mod/quiz/components/preflight-modal/preflight-modal.ts
index 4ec740b22..975f4ae42 100644
--- a/src/addons/mod/quiz/components/preflight-modal/preflight-modal.ts
+++ b/src/addons/mod/quiz/components/preflight-modal/preflight-modal.ts
@@ -23,6 +23,7 @@ import { AddonModQuizAccessRuleDelegate } from '../../services/access-rules-dele
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '../../services/quiz';
import { CoreDom } from '@singletons/dom';
import { CoreSharedModule } from '@/core/shared.module';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Modal that renders the access rules for a quiz.
@@ -39,12 +40,12 @@ export class AddonModQuizPreflightModalComponent implements OnInit {
@ViewChild('preflightFormEl') formElement?: ElementRef;
- @Input() title!: string;
+ @Input({ required: true }) title!: string;
@Input() quiz?: AddonModQuizQuizWSData;
@Input() attempt?: AddonModQuizAttemptWSData;
- @Input() prefetch?: boolean;
- @Input() siteId!: string;
- @Input() rules!: string[];
+ @Input({ transform: toBoolean }) prefetch = false;
+ @Input({ required: true }) siteId!: string;
+ @Input({ required: true }) rules!: string[];
preflightForm: FormGroup;
accessRulesData: { component: Type; data: Record}[] = []; // Component and data for each access rule.
diff --git a/src/addons/mod/quiz/components/question-card/question-card.ts b/src/addons/mod/quiz/components/question-card/question-card.ts
index 0f6c4c87a..b89c912cb 100644
--- a/src/addons/mod/quiz/components/question-card/question-card.ts
+++ b/src/addons/mod/quiz/components/question-card/question-card.ts
@@ -25,6 +25,6 @@ import { CoreQuestionQuestionForView } from '@features/question/services/questio
})
export class AddonModQuizQuestionCardComponent {
- @Input() question!: CoreQuestionQuestionForView;
+ @Input({ required: true }) question!: CoreQuestionQuestionForView;
}
diff --git a/src/addons/mod/scorm/components/toc/toc.ts b/src/addons/mod/scorm/components/toc/toc.ts
index 42199ba11..f91d0bbcf 100644
--- a/src/addons/mod/scorm/components/toc/toc.ts
+++ b/src/addons/mod/scorm/components/toc/toc.ts
@@ -35,9 +35,9 @@ export class AddonModScormTocComponent implements OnInit {
@Input() toc: AddonModScormTOCScoWithIcon[] = [];
@Input() attemptToContinue?: number;
@Input() selected?: number;
- @Input() moduleId!: number;
- @Input() courseId!: number;
- @Input() accessInfo!: AddonModScormGetScormAccessInformationWSResponse;
+ @Input({ required: true }) moduleId!: number;
+ @Input({ required: true }) courseId!: number;
+ @Input({ required: true }) accessInfo!: AddonModScormGetScormAccessInformationWSResponse;
@Input() mode = '';
isBrowse = false;
diff --git a/src/addons/mod/wiki/components/subwiki-picker/subwiki-picker.ts b/src/addons/mod/wiki/components/subwiki-picker/subwiki-picker.ts
index 878d918d3..adfb4821a 100644
--- a/src/addons/mod/wiki/components/subwiki-picker/subwiki-picker.ts
+++ b/src/addons/mod/wiki/components/subwiki-picker/subwiki-picker.ts
@@ -32,7 +32,7 @@ export class AddonModWikiSubwikiPickerComponent {
@Input() courseId?: number;
@Input() subwikis: AddonModWikiSubwikiListGrouping[] = [];
- @Input() currentSubwiki!: AddonModWikiSubwiki;
+ @Input({ required: true }) currentSubwiki!: AddonModWikiSubwiki;
/**
* Checks if the given subwiki is the one currently selected.
diff --git a/src/addons/mod/workshop/classes/assessment-strategy-component.ts b/src/addons/mod/workshop/classes/assessment-strategy-component.ts
index 1e9c85548..d9ffa8626 100644
--- a/src/addons/mod/workshop/classes/assessment-strategy-component.ts
+++ b/src/addons/mod/workshop/classes/assessment-strategy-component.ts
@@ -15,6 +15,7 @@
import { Component, Input } from '@angular/core';
import { AddonModWorkshopGetAssessmentFormFieldsParsedData } from '../services/workshop';
import { AddonModWorkshopSubmissionAssessmentWithFormData } from '../services/workshop-helper';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Base class for component to render an assessment strategy.
@@ -24,13 +25,13 @@ import { AddonModWorkshopSubmissionAssessmentWithFormData } from '../services/wo
})
export class AddonModWorkshopAssessmentStrategyBaseComponent {
- @Input() workshopId!: number;
- @Input() assessment!: AddonModWorkshopSubmissionAssessmentWithFormData;
- @Input() edit!: boolean;
- @Input() selectedValues!: AddonModWorkshopGetAssessmentFormFieldsParsedData[];
- @Input() fieldErrors!: Record;
- @Input() strategy!: string;
- @Input() moduleId!: number;
+ @Input({ required: true }) workshopId!: number;
+ @Input({ required: true }) assessment!: AddonModWorkshopSubmissionAssessmentWithFormData;
+ @Input({ required: true, transform: toBoolean }) edit = false;
+ @Input({ required: true }) selectedValues!: AddonModWorkshopGetAssessmentFormFieldsParsedData[];
+ @Input({ required: true }) fieldErrors!: Record;
+ @Input({ required: true }) strategy!: string;
+ @Input({ required: true }) moduleId!: number;
@Input() courseId?: number;
}
diff --git a/src/addons/mod/workshop/components/assessment-strategy/assessment-strategy.ts b/src/addons/mod/workshop/components/assessment-strategy/assessment-strategy.ts
index 503174cf5..1c1908047 100644
--- a/src/addons/mod/workshop/components/assessment-strategy/assessment-strategy.ts
+++ b/src/addons/mod/workshop/components/assessment-strategy/assessment-strategy.ts
@@ -42,6 +42,7 @@ import {
ADDON_MOD_WORKSHOP_COMPONENT,
AddonModWorkshopOverallFeedbackMode,
} from '@addons/mod/workshop/constants';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component that displays workshop assessment strategy form.
@@ -52,12 +53,12 @@ import {
})
export class AddonModWorkshopAssessmentStrategyComponent implements OnInit, OnDestroy {
- @Input() workshop!: AddonModWorkshopData;
- @Input() access!: AddonModWorkshopGetWorkshopAccessInformationWSResponse;
- @Input() assessmentId!: number;
- @Input() userId!: number;
- @Input() strategy!: string;
- @Input() edit = false;
+ @Input({ required: true }) workshop!: AddonModWorkshopData;
+ @Input({ required: true }) access!: AddonModWorkshopGetWorkshopAccessInformationWSResponse;
+ @Input({ required: true }) assessmentId!: number;
+ @Input({ required: true }) userId!: number;
+ @Input({ required: true }) strategy!: string;
+ @Input({ transform: toBoolean }) edit = false;
@ViewChild('assessmentForm') formElement!: ElementRef;
diff --git a/src/addons/mod/workshop/components/assessment/assessment.ts b/src/addons/mod/workshop/components/assessment/assessment.ts
index 1e6464bc0..6fac33bd2 100644
--- a/src/addons/mod/workshop/components/assessment/assessment.ts
+++ b/src/addons/mod/workshop/components/assessment/assessment.ts
@@ -36,12 +36,12 @@ import { AddonModWorkshopOffline } from '../../services/workshop-offline';
})
export class AddonModWorkshopAssessmentComponent implements OnInit {
- @Input() assessment!: AddonModWorkshopSubmissionAssessmentWithFormData;
- @Input() courseId!: number;
- @Input() workshop!: AddonModWorkshopData;
- @Input() access!: AddonModWorkshopGetWorkshopAccessInformationWSResponse;
- @Input() submission!: AddonModWorkshopSubmissionDataWithOfflineData;
- @Input() module!: CoreCourseModuleData;
+ @Input({ required: true }) assessment!: AddonModWorkshopSubmissionAssessmentWithFormData;
+ @Input({ required: true }) courseId!: number;
+ @Input({ required: true }) workshop!: AddonModWorkshopData;
+ @Input({ required: true }) access!: AddonModWorkshopGetWorkshopAccessInformationWSResponse;
+ @Input({ required: true }) submission!: AddonModWorkshopSubmissionDataWithOfflineData;
+ @Input({ required: true }) module!: CoreCourseModuleData;
canViewAssessment = false;
canSelfAssess = false;
diff --git a/src/addons/mod/workshop/components/phase-modal/phase-modal.ts b/src/addons/mod/workshop/components/phase-modal/phase-modal.ts
index 95bc52faa..a6a138526 100644
--- a/src/addons/mod/workshop/components/phase-modal/phase-modal.ts
+++ b/src/addons/mod/workshop/components/phase-modal/phase-modal.ts
@@ -18,6 +18,7 @@ import { ModalController } from '@singletons';
import { AddonModWorkshopPhaseData, AddonModWorkshopPhaseTaskData } from '../../services/workshop';
import { AddonModWorkshopPhase } from '../../constants';
import { CoreSharedModule } from '@/core/shared.module';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Page that displays the phase info modal.
@@ -31,10 +32,10 @@ import { CoreSharedModule } from '@/core/shared.module';
})
export class AddonModWorkshopPhaseInfoModalComponent implements OnInit {
- @Input() phases!: AddonModWorkshopPhaseDataWithSwitch[];
- @Input() workshopPhase!: AddonModWorkshopPhase;
- @Input() showSubmit = false;
- @Input() externalUrl!: string;
+ @Input({ required: true }) phases!: AddonModWorkshopPhaseDataWithSwitch[];
+ @Input({ required: true }) workshopPhase!: AddonModWorkshopPhase;
+ @Input({ transform: toBoolean }) showSubmit = false;
+ @Input({ required: true }) externalUrl!: string;
ngOnInit(): void {
diff --git a/src/addons/mod/workshop/components/submission/submission.ts b/src/addons/mod/workshop/components/submission/submission.ts
index 53ae4a891..0b3481f09 100644
--- a/src/addons/mod/workshop/components/submission/submission.ts
+++ b/src/addons/mod/workshop/components/submission/submission.ts
@@ -30,6 +30,7 @@ import {
} from '../../services/workshop-helper';
import { AddonModWorkshopOffline } from '../../services/workshop-offline';
import { ADDON_MOD_WORKSHOP_COMPONENT, ADDON_MOD_WORKSHOP_PAGE_NAME, AddonModWorkshopPhase } from '@addons/mod/workshop/constants';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component that displays workshop submission.
@@ -41,13 +42,13 @@ import { ADDON_MOD_WORKSHOP_COMPONENT, ADDON_MOD_WORKSHOP_PAGE_NAME, AddonModWor
})
export class AddonModWorkshopSubmissionComponent implements OnInit {
- @Input() submission!: AddonModWorkshopSubmissionDataWithOfflineData;
- @Input() module!: CoreCourseModuleData;
- @Input() workshop!: AddonModWorkshopData;
- @Input() access!: AddonModWorkshopGetWorkshopAccessInformationWSResponse;
- @Input() courseId!: number;
+ @Input({ required: true }) submission!: AddonModWorkshopSubmissionDataWithOfflineData;
+ @Input({ required: true }) module!: CoreCourseModuleData;
+ @Input({ required: true }) workshop!: AddonModWorkshopData;
+ @Input({ required: true }) access!: AddonModWorkshopGetWorkshopAccessInformationWSResponse;
+ @Input({ required: true }) courseId!: number;
@Input() assessment?: AddonModWorkshopSubmissionAssessmentWithFormData;
- @Input() summary = false;
+ @Input({ transform: toBoolean }) summary = false;
component = ADDON_MOD_WORKSHOP_COMPONENT;
componentId?: number;
diff --git a/src/addons/mod/workshop/pages/submission/submission.html b/src/addons/mod/workshop/pages/submission/submission.html
index dde29a697..0a4ed5029 100644
--- a/src/addons/mod/workshop/pages/submission/submission.html
+++ b/src/addons/mod/workshop/pages/submission/submission.html
@@ -88,8 +88,8 @@
{{ 'addon.mod_workshop.givengrades' | translate }}
-
+
-
+
{{ 'core.openinbrowser' | translate }}
diff --git a/src/core/features/mainmenu/components/user-menu-button/user-menu-button.ts b/src/core/features/mainmenu/components/user-menu-button/user-menu-button.ts
index 369dfc41e..a15b2a8e7 100644
--- a/src/core/features/mainmenu/components/user-menu-button/user-menu-button.ts
+++ b/src/core/features/mainmenu/components/user-menu-button/user-menu-button.ts
@@ -22,6 +22,7 @@ import { CoreSites } from '@services/sites';
import { CoreModals } from '@services/modals';
import { CoreMainMenuUserMenuTourComponent } from '../user-menu-tour/user-menu-tour';
import { CoreMainMenuPage } from '@features/mainmenu/pages/menu/menu';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component to display an avatar on the header to open user menu.
@@ -35,7 +36,7 @@ import { CoreMainMenuPage } from '@features/mainmenu/pages/menu/menu';
})
export class CoreMainMenuUserButtonComponent implements OnInit {
- @Input() alwaysShow = false;
+ @Input({ transform: toBoolean }) alwaysShow = false;
siteInfo?: CoreSiteInfo;
isMainScreen = false;
userTour: CoreUserTourDirectiveOptions = {
diff --git a/src/core/features/mainmenu/components/user-menu/user-menu.html b/src/core/features/mainmenu/components/user-menu/user-menu.html
index 6dc40ca15..7063eba8e 100644
--- a/src/core/features/mainmenu/components/user-menu/user-menu.html
+++ b/src/core/features/mainmenu/components/user-menu/user-menu.html
@@ -17,7 +17,7 @@
-
+
diff --git a/src/core/features/question/classes/base-question-component.ts b/src/core/features/question/classes/base-question-component.ts
index 09642ba35..78fc86068 100644
--- a/src/core/features/question/classes/base-question-component.ts
+++ b/src/core/features/question/classes/base-question-component.ts
@@ -24,6 +24,7 @@ import { CoreIonicColorNames } from '@singletons/colors';
import { CoreLogger } from '@singletons/logger';
import { CoreQuestionBehaviourButton, CoreQuestionHelper, CoreQuestionQuestion } from '../services/question-helper';
import { ContextLevel } from '@/core/constants';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Base class for components to render a question.
@@ -37,11 +38,11 @@ export class CoreQuestionBaseComponent(); // Will emit when a behaviour button is clicked.
@Output() onAbort = new EventEmitter(); // Should emit an event if the question should be aborted.
diff --git a/src/core/features/question/components/question/question.ts b/src/core/features/question/components/question/question.ts
index 7932bcc1b..7a7fbf7ef 100644
--- a/src/core/features/question/components/question/question.ts
+++ b/src/core/features/question/components/question/question.ts
@@ -13,6 +13,7 @@
// limitations under the License.
import { ContextLevel } from '@/core/constants';
+import { toBoolean } from '@/core/transforms/boolean';
import { Component, Input, Output, OnInit, EventEmitter, ChangeDetectorRef, Type, ElementRef } from '@angular/core';
import { AsyncDirective } from '@classes/async-directive';
import { CorePromisedValue } from '@classes/promised-value';
@@ -41,11 +42,11 @@ export class CoreQuestionComponent implements OnInit, AsyncDirective {
@Input() componentId?: number; // ID of the component the question belongs to.
@Input() attemptId?: number; // Attempt ID.
@Input() usageId?: number; // Usage ID.
- @Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
+ @Input({ transform: toBoolean }) offlineEnabled = false; // Whether the question can be answered in offline.
@Input() contextLevel?: ContextLevel; // The context level.
@Input() contextInstanceId?: number; // The instance ID related to the context.
@Input() courseId?: number; // Course ID the question belongs to (if any). It can be used to improve performance with filters.
- @Input() review?: boolean; // Whether the user is in review mode.
+ @Input({ transform: toBoolean }) review = false; // Whether the user is in review mode.
@Input() preferredBehaviour?: string; // Behaviour to use.
@Output() buttonClicked = new EventEmitter(); // Will emit when a behaviour button is clicked.
@Output() onAbort= new EventEmitter(); // Will emit an event if the question should be aborted.
@@ -78,8 +79,6 @@ export class CoreQuestionComponent implements OnInit, AsyncDirective {
* @inheritdoc
*/
async ngOnInit(): Promise {
- this.offlineEnabled = CoreUtils.isTrueOrOne(this.offlineEnabled);
-
if (!this.question || (this.question.type != 'random' &&
!CoreQuestionDelegate.isQuestionSupported(this.question.type))) {
this.promisedReady.resolve();
diff --git a/src/core/features/rating/components/aggregate/aggregate.ts b/src/core/features/rating/components/aggregate/aggregate.ts
index 7837e6343..9687202ed 100644
--- a/src/core/features/rating/components/aggregate/aggregate.ts
+++ b/src/core/features/rating/components/aggregate/aggregate.ts
@@ -33,12 +33,12 @@ import { CoreEventObserver, CoreEvents } from '@singletons/events';
})
export class CoreRatingAggregateComponent implements OnChanges, OnDestroy {
- @Input() ratingInfo!: CoreRatingInfo;
- @Input() contextLevel!: ContextLevel;
- @Input() instanceId!: number;
- @Input() itemId!: number;
- @Input() aggregateMethod!: number;
- @Input() scaleId!: number;
+ @Input({ required: true }) ratingInfo!: CoreRatingInfo;
+ @Input({ required: true }) contextLevel!: ContextLevel;
+ @Input({ required: true }) instanceId!: number;
+ @Input({ required: true }) itemId!: number;
+ @Input({ required: true }) aggregateMethod!: number;
+ @Input({ required: true }) scaleId!: number;
@Input() courseId?: number;
item?: CoreRatingInfoItem;
diff --git a/src/core/features/rating/components/rate/rate.ts b/src/core/features/rating/components/rate/rate.ts
index a7b9c562e..5768ce812 100644
--- a/src/core/features/rating/components/rate/rate.ts
+++ b/src/core/features/rating/components/rate/rate.ts
@@ -37,15 +37,15 @@ import { CoreEventObserver, CoreEvents } from '@singletons/events';
})
export class CoreRatingRateComponent implements OnChanges, OnDestroy {
- @Input() ratingInfo!: CoreRatingInfo;
- @Input() contextLevel!: ContextLevel; // Context level: course, module, user, etc.
- @Input() instanceId!: number; // Context instance id.
- @Input() itemId!: number; // Item id. Example: forum post id.
- @Input() itemSetId!: number; // Item set id. Example: forum discussion id.
- @Input() courseId!: number;
- @Input() aggregateMethod!: number;
- @Input() scaleId!: number;
- @Input() userId!: number;
+ @Input({ required: true }) ratingInfo!: CoreRatingInfo;
+ @Input({ required: true }) contextLevel!: ContextLevel; // Context level: course, module, user, etc.
+ @Input({ required: true }) instanceId!: number; // Context instance id.
+ @Input({ required: true }) itemId!: number; // Item id. Example: forum post id.
+ @Input({ required: true }) itemSetId!: number; // Item set id. Example: forum discussion id.
+ @Input({ required: true }) courseId!: number;
+ @Input({ required: true }) aggregateMethod!: number;
+ @Input({ required: true }) scaleId!: number;
+ @Input({ required: true }) userId!: number;
@Output() protected onLoading: EventEmitter; // Eevent that indicates whether the component is loading data.
@Output() protected onUpdate: EventEmitter; // Event emitted when the rating is updated online.
diff --git a/src/core/features/rating/components/ratings/ratings.ts b/src/core/features/rating/components/ratings/ratings.ts
index 5dc9aa6f8..005476c11 100644
--- a/src/core/features/rating/components/ratings/ratings.ts
+++ b/src/core/features/rating/components/ratings/ratings.ts
@@ -31,14 +31,14 @@ import { ModalController } from '@singletons';
})
export class CoreRatingRatingsComponent implements OnInit {
- @Input() contextLevel!: ContextLevel;
- @Input() instanceId!: number;
- @Input() ratingComponent!: string;
- @Input() ratingArea!: string;
- @Input() aggregateMethod!: number;
- @Input() itemId!: number;
- @Input() scaleId!: number;
- @Input() courseId!: number;
+ @Input({ required: true }) contextLevel!: ContextLevel;
+ @Input({ required: true }) instanceId!: number;
+ @Input({ required: true }) ratingComponent!: string;
+ @Input({ required: true }) ratingArea!: string;
+ @Input({ required: true }) aggregateMethod!: number;
+ @Input({ required: true }) itemId!: number;
+ @Input({ required: true }) scaleId!: number;
+ @Input({ required: true }) courseId!: number;
loaded = false;
ratings: CoreRatingItemRating[] = [];
diff --git a/src/core/features/reportbuilder/components/report-column/report-column.ts b/src/core/features/reportbuilder/components/report-column/report-column.ts
index 5d086c93a..427000145 100644
--- a/src/core/features/reportbuilder/components/report-column/report-column.ts
+++ b/src/core/features/reportbuilder/components/report-column/report-column.ts
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { toBoolean } from '@/core/transforms/boolean';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { CoreReportBuilder } from '@features/reportbuilder/services/reportbuilder';
@@ -22,15 +23,15 @@ import { CoreReportBuilder } from '@features/reportbuilder/services/reportbuilde
})
export class CoreReportBuilderReportColumnComponent {
- @Input() isExpanded = false;
- @Input() isExpandable = false;
- @Input() showFirstTitle = false;
- @Input() columnIndex!: number;
- @Input() rowIndex!: number;
- @Input() column!: string | number;
- @Input() contextId!: number;
- @Input() header!: string;
- @Input() source!: string;
+ @Input({ transform: toBoolean }) isExpanded = false;
+ @Input({ transform: toBoolean }) isExpandable = false;
+ @Input({ transform: toBoolean }) showFirstTitle = false;
+ @Input({ required: true }) columnIndex!: number;
+ @Input({ required: true }) rowIndex!: number;
+ @Input({ required: true }) column!: string | number;
+ @Input({ required: true }) contextId!: number;
+ @Input({ required: true }) header!: string;
+ @Input({ required: true }) source!: string;
@Output() onToggleRow: EventEmitter = new EventEmitter();
isString = (value: unknown): boolean => CoreReportBuilder.isString(value);
diff --git a/src/core/features/reportbuilder/components/report-detail/report-detail.ts b/src/core/features/reportbuilder/components/report-detail/report-detail.ts
index 5be288272..45073ea05 100644
--- a/src/core/features/reportbuilder/components/report-detail/report-detail.ts
+++ b/src/core/features/reportbuilder/components/report-detail/report-detail.ts
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { toBoolean } from '@/core/transforms/boolean';
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { CoreError } from '@classes/errors/error';
import {
@@ -40,8 +41,8 @@ import { map } from 'rxjs/operators';
})
export class CoreReportBuilderReportDetailComponent implements OnInit {
- @Input() reportId!: string;
- @Input() isBlock = true;
+ @Input({ required: true }) reportId!: string;
+ @Input({ transform: toBoolean }) isBlock = true;
@Input() perPage?: number;
@Input() layout: 'card' | 'table' | 'adaptative' = 'adaptative';
@Output() onReportLoaded = new EventEmitter();
diff --git a/src/core/features/reportbuilder/components/report-summary/report-summary.ts b/src/core/features/reportbuilder/components/report-summary/report-summary.ts
index 13b3650c5..7db580ef8 100644
--- a/src/core/features/reportbuilder/components/report-summary/report-summary.ts
+++ b/src/core/features/reportbuilder/components/report-summary/report-summary.ts
@@ -31,7 +31,7 @@ import { ModalController } from '@singletons';
})
export class CoreReportBuilderReportSummaryComponent implements OnInit {
- @Input() reportDetail!: CoreReportBuilderReportDetail;
+ @Input({ required: true }) reportDetail!: CoreReportBuilderReportDetail;
reportUrl!: string;
reportDetailToDisplay!: { title: string; text: string }[];
diff --git a/src/core/features/search/components/global-search-filters/global-search-filters.component.ts b/src/core/features/search/components/global-search-filters/global-search-filters.component.ts
index dbd15dc0a..c956f216e 100644
--- a/src/core/features/search/components/global-search-filters/global-search-filters.component.ts
+++ b/src/core/features/search/components/global-search-filters/global-search-filters.component.ts
@@ -24,6 +24,7 @@ import { CoreEvents } from '@singletons/events';
import { ModalController } from '@singletons';
import { CoreUtils } from '@services/utils/utils';
import { CoreSharedModule } from '@/core/shared.module';
+import { toBoolean } from '@/core/transforms/boolean';
type Filter = T & { checked: boolean };
@@ -43,7 +44,7 @@ export class CoreSearchGlobalSearchFiltersComponent implements OnInit {
allCourses: boolean | null = true;
courses: Filter[] = [];
- @Input() hideCourses?: boolean;
+ @Input({ transform: toBoolean }) hideCourses = false;
@Input() filters?: CoreSearchGlobalSearchFilters;
private newFilters: CoreSearchGlobalSearchFilters = {};
diff --git a/src/core/features/search/components/global-search-result/global-search-result.ts b/src/core/features/search/components/global-search-result/global-search-result.ts
index 7e60f15e6..62a215561 100644
--- a/src/core/features/search/components/global-search-result/global-search-result.ts
+++ b/src/core/features/search/components/global-search-result/global-search-result.ts
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { toBoolean } from '@/core/transforms/boolean';
import { Component, Input, Output, EventEmitter, OnChanges } from '@angular/core';
import { CoreSearchGlobalSearchResult, CoreSearchGlobalSearchResultContext } from '@features/search/services/global-search';
@@ -22,8 +23,8 @@ import { CoreSearchGlobalSearchResult, CoreSearchGlobalSearchResultContext } fro
})
export class CoreSearchGlobalSearchResultComponent implements OnChanges {
- @Input() result!: CoreSearchGlobalSearchResult;
- @Input() showCourse?: boolean;
+ @Input({ required: true }) result!: CoreSearchGlobalSearchResult;
+ @Input({ transform: toBoolean }) showCourse = true;
renderedContext: CoreSearchGlobalSearchResultContext | null = null;
renderedIcon: string | null = null;
@@ -46,7 +47,7 @@ export class CoreSearchGlobalSearchResultComponent implements OnChanges {
private computeRenderedContext(): CoreSearchGlobalSearchResultContext | null {
const context = { ...this.result.context } ?? {};
- if (this.showCourse === false) {
+ if (!this.showCourse) {
delete context.courseName;
}
diff --git a/src/core/features/search/components/search-box/search-box.ts b/src/core/features/search/components/search-box/search-box.ts
index 1db5989c8..6494339ec 100644
--- a/src/core/features/search/components/search-box/search-box.ts
+++ b/src/core/features/search/components/search-box/search-box.ts
@@ -15,11 +15,11 @@
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
import { CoreSites } from '@services/sites';
-import { CoreUtils } from '@services/utils/utils';
import { CoreSearchHistory } from '../../services/search-history.service';
import { Translate } from '@singletons';
import { CoreSearchHistoryDBRecord } from '../../services/search-history-db';
import { CoreForms } from '@singletons/form';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component to display a "search box".
@@ -41,11 +41,11 @@ export class CoreSearchBoxComponent implements OnInit {
@Input() searchLabel?: string; // Label to be used on action button.
@Input() placeholder?: string; // Placeholder text for search text input.
@Input() autocorrect = 'on'; // Enables/disable Autocorrection on search text input.
- @Input() spellcheck: string | boolean = true; // Enables/disable Spellchecker on search text input.
- @Input() autoFocus: string | boolean = false; // Enables/disable Autofocus when entering view.
+ @Input({ transform: toBoolean }) spellcheck = true; // Enables/disable Spellchecker on search text input.
+ @Input({ transform: toBoolean }) autoFocus = false; // Enables/disable Autofocus when entering view.
@Input() lengthCheck = 3; // Check value length before submit. If 0, any string will be submitted.
- @Input() showClear = true; // Show/hide clear button.
- @Input() disabled = false; // Disables the input text.
+ @Input({ transform: toBoolean }) showClear = true; // Show/hide clear button.
+ @Input({ transform: toBoolean }) disabled = false; // Disables the input text.
@Input() initialSearch = ''; // Initial search text.
/* If provided. It will save and display a history of searches for this particular Id.
@@ -72,8 +72,6 @@ export class CoreSearchBoxComponent implements OnInit {
ngOnInit(): void {
this.searchLabel = this.searchLabel || Translate.instant('core.search');
this.placeholder = this.placeholder || Translate.instant('core.search');
- this.spellcheck = CoreUtils.isTrueOrOne(this.spellcheck);
- this.showClear = CoreUtils.isTrueOrOne(this.showClear);
this.searchText = this.initialSearch;
if (this.searchArea) {
diff --git a/src/core/features/settings/pages/about/about.html b/src/core/features/settings/pages/about/about.html
index ce17902b3..83002f367 100644
--- a/src/core/features/settings/pages/about/about.html
+++ b/src/core/features/settings/pages/about/about.html
@@ -17,12 +17,12 @@
{{ 'core.settings.opensourcelicenses' | translate }}
-
{{ 'core.settings.privacypolicy' | translate }}
-
{{ 'core.settings.accessstatement' | translate }}
@@ -32,8 +32,8 @@
{{ 'core.settings.helpusimprove' | translate }}
-
+
{{ 'core.settings.legaldisclaimer' | translate }}
diff --git a/src/core/features/settings/pages/deviceinfo/deviceinfo.html b/src/core/features/settings/pages/deviceinfo/deviceinfo.html
index 08886bdc5..1eedc62d5 100644
--- a/src/core/features/settings/pages/deviceinfo/deviceinfo.html
+++ b/src/core/features/settings/pages/deviceinfo/deviceinfo.html
@@ -42,7 +42,7 @@
{{ 'core.settings.siteinfo' | translate }}
*
- {{ deviceInfo.siteUrl }}
+ {{ deviceInfo.siteUrl }}
{{ deviceInfo.siteVersion }}
{{ deviceInfo.siteId }}
@@ -51,7 +51,7 @@
{{ 'core.settings.filesystemroot' | translate }}
-
+
{{ deviceInfo.fileSystemRoot }}
diff --git a/src/core/features/settings/pages/licenses/licenses.html b/src/core/features/settings/pages/licenses/licenses.html
index 7710faa0f..eacf71709 100644
--- a/src/core/features/settings/pages/licenses/licenses.html
+++ b/src/core/features/settings/pages/licenses/licenses.html
@@ -14,30 +14,30 @@
-
+
{{ 'core.settings.opensourcelicenses' | translate }}
-
+
{{ 'core.view' | translate }}
- {{ license.name }}
+ {{ license.name }}
{{ license.name }} - {{ license.version }}
{{ 'core.settings.publisher' | translate }}{{ 'core.labelsep' | translate }} {{ license.publisher }}
{{ 'core.settings.license' | translate }}{{ 'core.labelsep' | translate }} {{ license.licenses }}
- {{ license.url }}
- {{ license.url }}
+ {{ license.email }}
+ [autoLogin]="false" [ariaLabel]="'core.view' | translate">
diff --git a/src/core/features/sharedfiles/components/list-modal/list-modal.ts b/src/core/features/sharedfiles/components/list-modal/list-modal.ts
index f084b0cec..6138c50fd 100644
--- a/src/core/features/sharedfiles/components/list-modal/list-modal.ts
+++ b/src/core/features/sharedfiles/components/list-modal/list-modal.ts
@@ -13,6 +13,7 @@
// limitations under the License.
import { CoreSharedModule } from '@/core/shared.module';
+import { toBoolean } from '@/core/transforms/boolean';
import { Component, OnInit, Input } from '@angular/core';
import { FileEntry } from '@awesome-cordova-plugins/file/ngx';
@@ -36,10 +37,10 @@ export class CoreSharedFilesListModalComponent implements OnInit {
@Input() siteId?: string;
@Input() mimetypes?: string[];
- @Input() manage?: boolean;
- @Input() pick?: boolean; // To pick a file you MUST use a modal.
+ @Input({ transform: toBoolean }) manage = false;
+ @Input({ transform: toBoolean }) pick = false; // To pick a file you MUST use a modal.
@Input() path?: string;
- @Input() hideSitePicker?: boolean;
+ @Input({ transform: toBoolean }) hideSitePicker = false;
title?: string;
diff --git a/src/core/features/sharedfiles/components/list/list.ts b/src/core/features/sharedfiles/components/list/list.ts
index 221a04295..c35c1944d 100644
--- a/src/core/features/sharedfiles/components/list/list.ts
+++ b/src/core/features/sharedfiles/components/list/list.ts
@@ -21,6 +21,7 @@ import { CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites';
import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CorePath } from '@singletons/path';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component to display the list of shared files, either as a modal or inside a page.
@@ -33,11 +34,11 @@ export class CoreSharedFilesListComponent implements OnInit, OnDestroy {
@Input() siteId?: string;
@Input() mimetypes?: string[];
- @Input() isModal?: boolean; // Whether the component is loaded in a modal.
- @Input() manage?: boolean;
- @Input() pick?: boolean; // To pick a file you MUST use a modal.
+ @Input({ transform: toBoolean }) isModal = false; // Whether the component is loaded in a modal.
+ @Input({ transform: toBoolean }) manage = false;
+ @Input({ transform: toBoolean }) pick = false; // To pick a file you MUST use a modal.
@Input() path?: string;
- @Input() showSitePicker?: boolean;
+ @Input({ transform: toBoolean }) showSitePicker = false;
@Output() onPathChanged = new EventEmitter();
@Output() onFilePicked = new EventEmitter();
diff --git a/src/core/features/siteplugins/classes/call-ws-click-directive.ts b/src/core/features/siteplugins/classes/call-ws-click-directive.ts
index e09d7fe0e..43f4b8bd2 100644
--- a/src/core/features/siteplugins/classes/call-ws-click-directive.ts
+++ b/src/core/features/siteplugins/classes/call-ws-click-directive.ts
@@ -16,10 +16,10 @@ import { Input, OnInit, ElementRef, Directive } from '@angular/core';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text';
-import { CoreUtils } from '@services/utils/utils';
import { Translate } from '@singletons';
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
import { CoreSitePluginsCallWSBaseDirective } from './call-ws-directive';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Base class for directives to call a WS when the element is clicked.
@@ -30,7 +30,7 @@ import { CoreSitePluginsCallWSBaseDirective } from './call-ws-directive';
export class CoreSitePluginsCallWSOnClickBaseDirective extends CoreSitePluginsCallWSBaseDirective implements OnInit {
@Input() confirmMessage?: string; // Message to confirm the action. If not supplied, no confirmation. If empty, default message.
- @Input() showError?: boolean | string; // Whether to show an error message if the WS call fails. Defaults to true.
+ @Input({ transform: toBoolean }) showError = true; // Whether to show an error message if the WS call fails.
constructor(
element: ElementRef,
@@ -72,7 +72,7 @@ export class CoreSitePluginsCallWSOnClickBaseDirective extends CoreSitePluginsCa
try {
await super.callWS();
} catch (error) {
- if (this.showError === undefined || CoreUtils.isTrueOrOne(this.showError)) {
+ if (this.showError) {
CoreDomUtils.showErrorModalDefault(
error,
Translate.instant('core.serverconnection', {
diff --git a/src/core/features/siteplugins/classes/call-ws-directive.ts b/src/core/features/siteplugins/classes/call-ws-directive.ts
index f17b7d8a4..ead49d373 100644
--- a/src/core/features/siteplugins/classes/call-ws-directive.ts
+++ b/src/core/features/siteplugins/classes/call-ws-directive.ts
@@ -27,7 +27,7 @@ import { CoreFormFields, CoreForms } from '@singletons/form';
@Directive()
export class CoreSitePluginsCallWSBaseDirective implements OnInit, OnDestroy {
- @Input() name!: string; // The name of the WS to call.
+ @Input({ required: true }) name!: string; // The name of the WS to call.
@Input() params?: Record; // The params for the WS call.
@Input() preSets?: CoreSiteWSPreSets; // The preSets for the WS call.
@Input() useOtherDataForWS?: string[] | unknown; // Whether to include other data in the params for the WS.
diff --git a/src/core/features/siteplugins/components/assign-feedback/assign-feedback.ts b/src/core/features/siteplugins/components/assign-feedback/assign-feedback.ts
index 213f4361a..26050d2d6 100644
--- a/src/core/features/siteplugins/components/assign-feedback/assign-feedback.ts
+++ b/src/core/features/siteplugins/components/assign-feedback/assign-feedback.ts
@@ -17,6 +17,7 @@ import { Component, OnInit, Input } from '@angular/core';
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '@addons/mod/assign/services/assign';
import { AddonModAssignFeedbackDelegate } from '@addons/mod/assign/services/feedback-delegate';
import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/classes/compile-init-component';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component that displays an assign feedback plugin created using a site plugin.
@@ -28,13 +29,13 @@ import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/class
})
export class CoreSitePluginsAssignFeedbackComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
- @Input() assign!: AddonModAssignAssign; // The assignment.
- @Input() submission!: AddonModAssignSubmission; // The submission.
- @Input() plugin!: AddonModAssignPlugin; // The plugin object.
- @Input() userId!: number; // The user ID of the submission.
+ @Input({ required: true }) assign!: AddonModAssignAssign; // The assignment.
+ @Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
+ @Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
+ @Input({ required: true }) userId!: number; // The user ID of the submission.
@Input() configs?: Record; // The configs for the plugin.
- @Input() canEdit = false; // Whether the user can edit.
- @Input() edit = false; // Whether the user is editing.
+ @Input({ transform: toBoolean }) canEdit = false; // Whether the user can edit.
+ @Input({ transform: toBoolean }) edit = false; // Whether the user is editing.
/**
* @inheritdoc
diff --git a/src/core/features/siteplugins/components/assign-submission/assign-submission.ts b/src/core/features/siteplugins/components/assign-submission/assign-submission.ts
index ed7232587..6fdf3d7be 100644
--- a/src/core/features/siteplugins/components/assign-submission/assign-submission.ts
+++ b/src/core/features/siteplugins/components/assign-submission/assign-submission.ts
@@ -17,6 +17,7 @@ import { Component, OnInit, Input } from '@angular/core';
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '@addons/mod/assign/services/assign';
import { AddonModAssignSubmissionDelegate } from '@addons/mod/assign/services/submission-delegate';
import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/classes/compile-init-component';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component that displays an assign submission plugin created using a site plugin.
@@ -28,12 +29,12 @@ import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/class
})
export class CoreSitePluginsAssignSubmissionComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
- @Input() assign!: AddonModAssignAssign; // The assignment.
- @Input() submission!: AddonModAssignSubmission; // The submission.
- @Input() plugin!: AddonModAssignPlugin; // The plugin object.
+ @Input({ required: true }) assign!: AddonModAssignAssign; // The assignment.
+ @Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
+ @Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
@Input() configs?: Record; // The configs for the plugin.
- @Input() edit = false; // Whether the user is editing.
- @Input() allowOffline = false; // Whether to allow offline.
+ @Input({ transform: toBoolean }) edit = false; // Whether the user is editing.
+ @Input({ transform: toBoolean }) allowOffline = false; // Whether to allow offline.
/**
* @inheritdoc
diff --git a/src/core/features/siteplugins/components/module-index/module-index.ts b/src/core/features/siteplugins/components/module-index/module-index.ts
index 6d6291235..49f51aca9 100644
--- a/src/core/features/siteplugins/components/module-index/module-index.ts
+++ b/src/core/features/siteplugins/components/module-index/module-index.ts
@@ -41,8 +41,8 @@ import { CoreSitePluginsPluginContentComponent, CoreSitePluginsPluginContentLoad
})
export class CoreSitePluginsModuleIndexComponent implements OnInit, OnDestroy, CoreCourseModuleMainComponent {
- @Input() module!: CoreCourseModuleData; // The module.
- @Input() courseId!: number; // Course ID the module belongs to.
+ @Input({ required: true }) module!: CoreCourseModuleData; // The module.
+ @Input({ required: true }) courseId!: number; // Course ID the module belongs to.
@Input() pageTitle?: string; // Current page title. It can be used by the "new-content" directives.
@ViewChild(CoreSitePluginsPluginContentComponent) content?: CoreSitePluginsPluginContentComponent;
diff --git a/src/core/features/siteplugins/components/plugin-content/plugin-content.ts b/src/core/features/siteplugins/components/plugin-content/plugin-content.ts
index 49634c4a9..6a501b8d8 100644
--- a/src/core/features/siteplugins/components/plugin-content/plugin-content.ts
+++ b/src/core/features/siteplugins/components/plugin-content/plugin-content.ts
@@ -50,7 +50,7 @@ export class CoreSitePluginsPluginContentComponent implements OnInit, DoCheck {
@ViewChild('compile') compileComponent?: CoreCompileHtmlComponent;
@HostBinding('class') @Input() component = '';
- @Input() method!: string;
+ @Input({ required: true }) method!: string;
@Input() args?: Record;
@Input() initResult?: CoreSitePluginsContent | null; // Result of the init WS call of the handler.
@Input() data: Record = {}; // Data to pass to the component.
diff --git a/src/core/features/siteplugins/components/question-behaviour/question-behaviour.ts b/src/core/features/siteplugins/components/question-behaviour/question-behaviour.ts
index 8eed77776..382051be7 100644
--- a/src/core/features/siteplugins/components/question-behaviour/question-behaviour.ts
+++ b/src/core/features/siteplugins/components/question-behaviour/question-behaviour.ts
@@ -13,6 +13,7 @@
// limitations under the License.
import { ContextLevel } from '@/core/constants';
+import { toBoolean } from '@/core/transforms/boolean';
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { CoreQuestionBehaviourDelegate } from '@features/question/services/behaviour-delegate';
@@ -33,11 +34,11 @@ export class CoreSitePluginsQuestionBehaviourComponent extends CoreSitePluginsCo
@Input() component?: string; // The component the question belongs to.
@Input() componentId?: number; // ID of the component the question belongs to.
@Input() attemptId?: number; // Attempt ID.
- @Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
+ @Input({ transform: toBoolean }) offlineEnabled = false; // Whether the question can be answered in offline.
@Input() contextLevel?: ContextLevel; // The context level.
@Input() contextInstanceId?: number; // The instance ID related to the context.
@Input() courseId?: number; // Course ID the question belongs to (if any). It can be used to improve performance with filters.
- @Input() review?: boolean; // Whether the user is in review mode.
+ @Input({ transform: toBoolean }) review = false; // Whether the user is in review mode.
@Input() preferredBehaviour?: string; // Preferred behaviour.
@Output() buttonClicked = new EventEmitter(); // Will emit when a behaviour button is clicked.
@Output() onAbort = new EventEmitter(); // Should emit an event if the question should be aborted.
@@ -58,6 +59,8 @@ export class CoreSitePluginsQuestionBehaviourComponent extends CoreSitePluginsCo
this.jsData.offlineEnabled = this.offlineEnabled;
this.jsData.contextLevel = this.contextLevel;
this.jsData.contextInstanceId = this.contextInstanceId;
+ this.jsData.courseId = this.courseId;
+ this.jsData.review = this.review;
this.jsData.buttonClicked = this.buttonClicked;
this.jsData.onAbort = this.onAbort;
diff --git a/src/core/features/siteplugins/components/question/question.ts b/src/core/features/siteplugins/components/question/question.ts
index 8c9bd7a39..686080ced 100644
--- a/src/core/features/siteplugins/components/question/question.ts
+++ b/src/core/features/siteplugins/components/question/question.ts
@@ -13,6 +13,7 @@
// limitations under the License.
import { ContextLevel } from '@/core/constants';
+import { toBoolean } from '@/core/transforms/boolean';
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { AddonModQuizQuestion } from '@features/question/classes/base-question-component';
@@ -34,11 +35,11 @@ export class CoreSitePluginsQuestionComponent extends CoreSitePluginsCompileInit
@Input() component?: string; // The component the question belongs to.
@Input() componentId?: number; // ID of the component the question belongs to.
@Input() attemptId?: number; // Attempt ID.
- @Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
+ @Input({ transform: toBoolean }) offlineEnabled = false; // Whether the question can be answered in offline.
@Input() contextLevel?: ContextLevel; // The context level.
@Input() contextInstanceId?: number; // The instance ID related to the context.
@Input() courseId?: number; // Course ID the question belongs to (if any). It can be used to improve performance with filters.
- @Input() review?: boolean; // Whether the user is in review mode.
+ @Input({ transform: toBoolean }) review = false; // Whether the user is in review mode.
@Input() preferredBehaviour?: string; // Preferred behaviour.
@Output() buttonClicked = new EventEmitter(); // Will emit when a behaviour button is clicked.
@Output() onAbort = new EventEmitter(); // Should emit an event if the question should be aborted.
diff --git a/src/core/features/siteplugins/components/quiz-access-rule/quiz-access-rule.ts b/src/core/features/siteplugins/components/quiz-access-rule/quiz-access-rule.ts
index 7c4c2a502..a030e888c 100644
--- a/src/core/features/siteplugins/components/quiz-access-rule/quiz-access-rule.ts
+++ b/src/core/features/siteplugins/components/quiz-access-rule/quiz-access-rule.ts
@@ -18,6 +18,7 @@ import { FormGroup } from '@angular/forms';
import { AddonModQuizAccessRuleDelegate } from '@addons/mod/quiz/services/access-rules-delegate';
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/classes/compile-init-component';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Component that displays a quiz access rule created using a site plugin.
@@ -32,7 +33,7 @@ export class CoreSitePluginsQuizAccessRuleComponent extends CoreSitePluginsCompi
@Input() rule?: string; // The name of the rule.
@Input() quiz?: AddonModQuizQuizWSData; // The quiz the rule belongs to.
@Input() attempt?: AddonModQuizAttemptWSData; // The attempt being started/continued.
- @Input() prefetch?: boolean; // Whether the user is prefetching the quiz.
+ @Input({ transform: toBoolean }) prefetch = false; // Whether the user is prefetching the quiz.
@Input() siteId?: string; // Site ID.
@Input() form?: FormGroup; // Form where to add the form control.
diff --git a/src/core/features/siteplugins/components/user-profile-field/user-profile-field.ts b/src/core/features/siteplugins/components/user-profile-field/user-profile-field.ts
index f67f48021..17a804768 100644
--- a/src/core/features/siteplugins/components/user-profile-field/user-profile-field.ts
+++ b/src/core/features/siteplugins/components/user-profile-field/user-profile-field.ts
@@ -13,6 +13,7 @@
// limitations under the License.
import { ContextLevel } from '@/core/constants';
+import { toBoolean } from '@/core/transforms/boolean';
import { Component, OnInit, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
@@ -32,9 +33,9 @@ import { CoreUserProfileFieldDelegate } from '@features/user/services/user-profi
export class CoreSitePluginsUserProfileFieldComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
@Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
- @Input() signup = false; // True if editing the field in signup. Defaults to false.
- @Input() edit = false; // True if editing the field. Defaults to false.
- @Input() disabled = false; // True if disabled. Defaults to false.
+ @Input({ transform: toBoolean }) signup = false; // True if editing the field in signup.
+ @Input({ transform: toBoolean }) edit = false; // True if editing the field.
+ @Input({ transform: toBoolean }) disabled = false; // True if disabled.
@Input() form?: FormGroup; // Form where to add the form control. Required if edit=true or signup=true.
@Input() registerAuth?: string; // Register auth method. E.g. 'email'.
@Input() contextLevel?: ContextLevel; // The context level.
diff --git a/src/core/features/siteplugins/components/workshop-assessment-strategy/workshop-assessment-strategy.ts b/src/core/features/siteplugins/components/workshop-assessment-strategy/workshop-assessment-strategy.ts
index 2030ab474..db0fc6949 100644
--- a/src/core/features/siteplugins/components/workshop-assessment-strategy/workshop-assessment-strategy.ts
+++ b/src/core/features/siteplugins/components/workshop-assessment-strategy/workshop-assessment-strategy.ts
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { toBoolean } from '@/core/transforms/boolean';
import { AddonWorkshopAssessmentStrategyDelegate } from '@addons/mod/workshop/services/assessment-strategy-delegate';
import { AddonModWorkshopGetAssessmentFormFieldsParsedData } from '@addons/mod/workshop/services/workshop';
import { AddonModWorkshopSubmissionAssessmentWithFormData } from '@addons/mod/workshop/services/workshop-helper';
@@ -28,13 +29,13 @@ import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/class
})
export class CoreSitePluginsWorkshopAssessmentStrategyComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
- @Input() workshopId!: number;
- @Input() assessment!: AddonModWorkshopSubmissionAssessmentWithFormData;
- @Input() edit!: boolean;
- @Input() selectedValues!: AddonModWorkshopGetAssessmentFormFieldsParsedData[];
- @Input() fieldErrors!: Record;
- @Input() strategy!: string;
- @Input() moduleId!: number;
+ @Input({ required: true }) workshopId!: number;
+ @Input({ required: true }) assessment!: AddonModWorkshopSubmissionAssessmentWithFormData;
+ @Input({ required: true, transform: toBoolean }) edit = false;
+ @Input({ required: true }) selectedValues!: AddonModWorkshopGetAssessmentFormFieldsParsedData[];
+ @Input({ required: true }) fieldErrors!: Record;
+ @Input({ required: true }) strategy!: string;
+ @Input({ required: true }) moduleId!: number;
@Input() courseId?: number;
/**
diff --git a/src/core/features/siteplugins/directives/call-ws-new-content.ts b/src/core/features/siteplugins/directives/call-ws-new-content.ts
index 729a8130a..7568380e4 100644
--- a/src/core/features/siteplugins/directives/call-ws-new-content.ts
+++ b/src/core/features/siteplugins/directives/call-ws-new-content.ts
@@ -15,12 +15,12 @@
import { Directive, Input, ElementRef, Optional } from '@angular/core';
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
import { CoreNavigator } from '@services/navigator';
-import { CoreUtils } from '@services/utils/utils';
import { Md5 } from 'ts-md5';
import { CoreSitePluginsCallWSOnClickBaseDirective } from '../classes/call-ws-click-directive';
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
import { CoreSitePlugins } from '../services/siteplugins';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Directive to call a WS when the element is clicked and load a new content passing the WS result as args. This new content
@@ -59,14 +59,14 @@ export class CoreSitePluginsCallWSNewContentDirective extends CoreSitePluginsCal
@Input() method?: string; // The method to get the new content. If not provided, use the same method as current page.
@Input() args?: Record; // The params to get the new content.
@Input() title?: string; // The title to display with the new content. Only if samePage=false.
- @Input() samePage?: boolean | string; // Whether to display the content in same page or open a new one. Defaults to new page.
+ @Input({ transform: toBoolean }) samePage = false; // Whether to display the content in same page or open a new one.
@Input() useOtherData?: string[] | unknown; // Whether to include other data in the args.
@Input() form?: string; // ID or name to identify a form. The form data will be retrieved and sent to the WS.
// JS variables to pass to the new page so they can be used in the template or JS.
// If true is supplied instead of an object, all initial variables from current page will be copied.
@Input() jsData?: Record | boolean;
@Input() newContentPreSets?: CoreSiteWSPreSets; // The preSets for the WS call of the new content.
- @Input() ptrEnabled?: boolean | string; // Whether PTR should be enabled in the new page. Defaults to true.
+ @Input({ transform: toBoolean }) ptrEnabled = true; // Whether PTR should be enabled in the new page.
constructor(
element: ElementRef,
@@ -93,7 +93,7 @@ export class CoreSitePluginsCallWSNewContentDirective extends CoreSitePluginsCal
jsData = this.parentContent?.data || {};
}
- if (CoreUtils.isTrueOrOne(this.samePage)) {
+ if (this.samePage) {
// Update the parent content (if it exists).
this.parentContent?.updateContent(args, this.component, this.method, jsData, this.newContentPreSets);
} else {
diff --git a/src/core/features/siteplugins/directives/call-ws.ts b/src/core/features/siteplugins/directives/call-ws.ts
index fc5bc0d3a..8b29b4d6b 100644
--- a/src/core/features/siteplugins/directives/call-ws.ts
+++ b/src/core/features/siteplugins/directives/call-ws.ts
@@ -16,10 +16,10 @@ import { Directive, Input, ElementRef, Optional } from '@angular/core';
import { Translate } from '@singletons';
import { CoreToasts } from '@services/toasts';
-import { CoreUtils } from '@services/utils/utils';
import { CoreNavigator } from '@services/navigator';
import { CoreSitePluginsCallWSOnClickBaseDirective } from '../classes/call-ws-click-directive';
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Directive to call a WS when the element is clicked. The action to do when the WS call is successful depends on the input data:
@@ -52,8 +52,8 @@ import { CoreSitePluginsPluginContentComponent } from '../components/plugin-cont
export class CoreSitePluginsCallWSDirective extends CoreSitePluginsCallWSOnClickBaseDirective {
@Input() successMessage?: string; // Message to show on success. If not supplied, no message. If empty, default message.
- @Input() goBackOnSuccess?: boolean | string; // Whether to go back if the WS call is successful.
- @Input() refreshOnSuccess?: boolean | string; // Whether to refresh the current view if the WS call is successful.
+ @Input({ transform: toBoolean }) goBackOnSuccess = false; // Whether to go back if the WS call is successful.
+ @Input({ transform: toBoolean }) refreshOnSuccess = false; // Whether to refresh the current view if the WS call is successful.
constructor(
element: ElementRef,
@@ -66,9 +66,9 @@ export class CoreSitePluginsCallWSDirective extends CoreSitePluginsCallWSOnClick
* @inheritdoc
*/
protected async wsCallSuccess(): Promise {
- if (CoreUtils.isTrueOrOne(this.goBackOnSuccess)) {
+ if (this.goBackOnSuccess) {
await CoreNavigator.back();
- } else if (CoreUtils.isTrueOrOne(this.refreshOnSuccess) && this.parentContent) {
+ } else if (this.refreshOnSuccess && this.parentContent) {
this.parentContent.refreshContent(true);
}
diff --git a/src/core/features/siteplugins/directives/new-content.ts b/src/core/features/siteplugins/directives/new-content.ts
index a22d57e2c..31d207fbb 100644
--- a/src/core/features/siteplugins/directives/new-content.ts
+++ b/src/core/features/siteplugins/directives/new-content.ts
@@ -17,10 +17,10 @@ import { Md5 } from 'ts-md5';
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
import { CoreNavigator } from '@services/navigator';
-import { CoreUtils } from '@services/utils/utils';
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
import { CoreSitePlugins } from '../services/siteplugins';
import { CoreForms } from '@singletons/form';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Directive to display a new site plugin content when clicked. This new content can be displayed in a new page or in the
@@ -51,14 +51,14 @@ export class CoreSitePluginsNewContentDirective implements OnInit {
@Input() method?: string; // The method to get the new content. If not provided, use the same method as current page.
@Input() args?: Record; // The params to get the new content.
@Input() title?: string; // The title to display with the new content. Only if samePage=false.
- @Input() samePage?: boolean | string; // Whether to display the content in same page or open a new one. Defaults to new page.
+ @Input({ transform: toBoolean }) samePage = false; // Whether to display the content in same page or open a new one.
@Input() useOtherData?: string[] | unknown; // Whether to include other data in the args.
@Input() form?: string; // ID or name to identify a form. The form data will be retrieved and sent to the WS.
// JS variables to pass to the new page so they can be used in the template or JS.
// If true is supplied instead of an object, all initial variables from current page will be copied.
@Input() jsData?: Record | boolean;
@Input() preSets?: CoreSiteWSPreSets; // The preSets for the WS call of the new content.
- @Input() ptrEnabled?: boolean | string; // Whether PTR should be enabled in the new page. Defaults to true.
+ @Input({ transform: toBoolean }) ptrEnabled = true; // Whether PTR should be enabled in the new page.
protected element: HTMLElement;
@@ -92,7 +92,7 @@ export class CoreSitePluginsNewContentDirective implements OnInit {
jsData = this.parentContent?.data || {};
}
- if (CoreUtils.isTrueOrOne(this.samePage)) {
+ if (this.samePage) {
// Update the parent content (if it exists).
this.parentContent?.updateContent(args, this.component, this.method, jsData, this.preSets);
} else {
diff --git a/src/core/features/user/classes/base-profilefield-component.ts b/src/core/features/user/classes/base-profilefield-component.ts
index ae8edbfe6..2c48f0f2d 100644
--- a/src/core/features/user/classes/base-profilefield-component.ts
+++ b/src/core/features/user/classes/base-profilefield-component.ts
@@ -13,6 +13,7 @@
// limitations under the License.
import { ContextLevel } from '@/core/constants';
+import { toBoolean } from '@/core/transforms/boolean';
import { Component, Input, OnInit } from '@angular/core';
import { FormGroup, Validators, FormControl } from '@angular/forms';
@@ -28,9 +29,9 @@ import { CoreUserProfileField } from '@features/user/services/user';
export abstract class CoreUserProfileFieldBaseComponent implements OnInit {
@Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
- @Input() signup = false; // True if editing the field in signup. Defaults to false.
- @Input() edit = false; // True if editing the field. Defaults to false.
- @Input() disabled = false; // True if disabled. Defaults to false.
+ @Input({ transform: toBoolean }) signup = false; // True if editing the field in signup.
+ @Input({ transform: toBoolean }) edit = false; // True if editing the field.
+ @Input({ transform: toBoolean }) disabled = false; // True if disabled.
@Input() form?: FormGroup; // Form where to add the form control. Required if edit=true or signup=true.
@Input() registerAuth?: string; // Register auth method. E.g. 'email'.
@Input() contextLevel?: ContextLevel; // The context level.
diff --git a/src/core/features/user/components/user-profile-field/user-profile-field.ts b/src/core/features/user/components/user-profile-field/user-profile-field.ts
index c3b4e82e5..9a33ee6ed 100644
--- a/src/core/features/user/components/user-profile-field/user-profile-field.ts
+++ b/src/core/features/user/components/user-profile-field/user-profile-field.ts
@@ -20,6 +20,7 @@ import { CoreUserProfileField } from '@features/user/services/user';
import { CoreUserProfileFieldDelegate } from '@features/user/services/user-profile-field-delegate';
import { CoreUtils } from '@services/utils/utils';
import { ContextLevel } from '@/core/constants';
+import { toBoolean } from '@/core/transforms/boolean';
/**
* Directive to render user profile field.
@@ -31,8 +32,8 @@ import { ContextLevel } from '@/core/constants';
export class CoreUserProfileFieldComponent implements OnInit {
@Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
- @Input() signup = false; // True if editing the field in signup. Defaults to false.
- @Input() edit = false; // True if editing the field. Defaults to false.
+ @Input({ transform: toBoolean }) signup = false; // True if editing the field in signup.
+ @Input({ transform: toBoolean }) edit = false; // True if editing the field.
@Input() form?: FormGroup; // Form where to add the form control. Required if edit=true or signup=true.
@Input() registerAuth?: string; // Register auth method. E.g. 'email'.
@Input() contextLevel?: ContextLevel; // The context level.
@@ -57,13 +58,13 @@ export class CoreUserProfileFieldComponent implements OnInit {
}
this.data.field = this.field;
- this.data.edit = CoreUtils.isTrueOrOne(this.edit);
+ this.data.edit = this.edit;
this.data.contextLevel = this.contextLevel;
this.data.contextInstanceId = this.contextInstanceId;
this.data.courseId = this.courseId;
if (this.edit) {
- this.data.signup = CoreUtils.isTrueOrOne(this.signup);
+ this.data.signup = this.signup;
this.data.disabled = 'locked' in this.field && CoreUtils.isTrueOrOne(this.field.locked);
this.data.form = this.form;
this.data.registerAuth = this.registerAuth;
diff --git a/src/core/features/user/pages/about/about.html b/src/core/features/user/pages/about/about.html
index f068fdc3e..7d7d43007 100644
--- a/src/core/features/user/pages/about/about.html
+++ b/src/core/features/user/pages/about/about.html
@@ -44,7 +44,7 @@
{{ 'core.user.email' | translate }}
-
+
{{ user.email }}
@@ -70,7 +70,7 @@
{{ 'core.user.phone1' | translate}}
-
+
{{ user.phone1 }}
@@ -78,7 +78,7 @@
{{ 'core.user.phone2' | translate}}
-
+
{{ user.phone2 }}
diff --git a/src/core/features/usertours/components/user-tour/user-tour.ts b/src/core/features/usertours/components/user-tour/user-tour.ts
index 2f278d8fc..0d0aacce6 100644
--- a/src/core/features/usertours/components/user-tour/user-tour.ts
+++ b/src/core/features/usertours/components/user-tour/user-tour.ts
@@ -52,9 +52,9 @@ const BACKDROP_DISMISS_SAFETY_TRESHOLD = 1000;
})
export class CoreUserToursUserTourComponent implements AfterViewInit, OnDestroy {
- @Input() container!: HTMLElement;
- @Input() id!: string;
- @Input() component!: unknown;
+ @Input({ required: true }) container!: HTMLElement;
+ @Input({ required: true }) id!: string;
+ @Input({ required: true }) component!: unknown;
@Input() componentProps?: Record;
@Input() focus?: HTMLElement;
@Input() side?: CoreUserToursSide;
diff --git a/src/core/features/viewer/components/text/text.ts b/src/core/features/viewer/components/text/text.ts
index 37029e7ba..a7ea45cda 100644
--- a/src/core/features/viewer/components/text/text.ts
+++ b/src/core/features/viewer/components/text/text.ts
@@ -14,6 +14,7 @@
import { ContextLevel } from '@/core/constants';
import { CoreSharedModule } from '@/core/shared.module';
+import { toBoolean } from '@/core/transforms/boolean';
import { Component, Input } from '@angular/core';
import { CoreFileEntry } from '@services/file-helper';
@@ -39,11 +40,11 @@ export class CoreViewerTextComponent {
@Input() component?: string; // Component to use in format-text.
@Input() componentId?: string | number; // Component ID to use in format-text.
@Input() files?: CoreFileEntry[]; // List of files.
- @Input() filter?: boolean; // Whether to filter the text.
+ @Input({ transform: toBoolean }) filter?: boolean; // Whether to filter the text.
@Input() contextLevel?: ContextLevel; // The context level.
@Input() instanceId?: number; // The instance ID related to the context.
@Input() courseId?: number; // Course ID the text belongs to. It can be used to improve performance with filters.
- @Input() displayCopyButton?: boolean; // Whether to display a button to copy the contents.
+ @Input({ transform: toBoolean }) displayCopyButton = false; // Whether to display a button to copy the contents.
/**
* Close modal.
diff --git a/src/core/features/viewer/pages/iframe/iframe.ts b/src/core/features/viewer/pages/iframe/iframe.ts
index 5b6ef0d13..ed468be0b 100644
--- a/src/core/features/viewer/pages/iframe/iframe.ts
+++ b/src/core/features/viewer/pages/iframe/iframe.ts
@@ -31,10 +31,7 @@ export class CoreViewerIframePage implements OnInit {
async ngOnInit(): Promise {
this.title = CoreNavigator.getRouteParam('title');
this.url = CoreNavigator.getRouteParam('url');
- const autoLoginParam = CoreNavigator.getRouteParam('autoLogin') ?? true;
- this.autoLogin = typeof autoLoginParam === 'boolean' ?
- autoLoginParam :
- autoLoginParam !== 'no'; // Support deprecated values yes/no/check.
+ this.autoLogin = CoreNavigator.getRouteBooleanParam('autoLogin') ?? true;
}
}
diff --git a/src/core/transforms/boolean.ts b/src/core/transforms/boolean.ts
new file mode 100644
index 000000000..88fc7b961
--- /dev/null
+++ b/src/core/transforms/boolean.ts
@@ -0,0 +1,34 @@
+// (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.
+
+/**
+ * Transform an Input value to a boolean.
+ * False values are: 0, '0', 'false', false, undefined, null.
+ * Please notice that empty strings are considered true for consistency with HTML.
+ *
+ * @param value Value to transform.
+ * @returns Transformed value.
+ */
+export function toBoolean(value: unknown): boolean {
+ if (value === undefined || value === null) {
+ return false;
+ }
+
+ if (value === '') {
+ // Empty string is considered true for consistency with HTML, where putting an attribute without value means true.
+ return true;
+ }
+
+ return !(value === false || value === 'false' || Number(value) === 0);
+}