MOBILE-4612 core: Create and use toBoolean input transform
parent
3d7cfeba42
commit
d45fc9c7a7
|
@ -19,6 +19,7 @@ import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreEnrolledCourseDataWithOptions } from '@features/courses/services/courses-helper';
|
import { CoreEnrolledCourseDataWithOptions } from '@features/courses/services/courses-helper';
|
||||||
import { AddonBlockTimelineDayEvents } from '@addons/block/timeline/classes/section';
|
import { AddonBlockTimelineDayEvents } from '@addons/block/timeline/classes/section';
|
||||||
import { CoreSharedModule } from '@/core/shared.module';
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directive to render a list of events in course overview.
|
* 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() events: AddonBlockTimelineDayEvents[] = []; // The events to render.
|
||||||
@Input() course?: CoreEnrolledCourseDataWithOptions; // Whether to show the course name.
|
@Input() course?: CoreEnrolledCourseDataWithOptions; // Whether to show the course name.
|
||||||
@Input() showInlineCourse = true; // Whether to show the course name within event items.
|
@Input({ transform: toBoolean }) showInlineCourse = true; // Whether to show the course name within event items.
|
||||||
@Input() canLoadMore = false; // Whether more events can be loaded.
|
@Input({ transform: toBoolean }) canLoadMore = false; // Whether more events can be loaded.
|
||||||
@Input() loadingMore = false; // Whether loading is ongoing.
|
@Input({ transform: toBoolean }) loadingMore = false; // Whether loading is ongoing.
|
||||||
@Output() loadMore = new EventEmitter(); // Notify that more events should be loaded.
|
@Output() loadMore = new EventEmitter(); // Notify that more events should be loaded.
|
||||||
|
|
||||||
colorizeIcons = false;
|
colorizeIcons = false;
|
||||||
|
|
|
@ -53,6 +53,7 @@ import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
|
||||||
import { CoreUrl } from '@singletons/url';
|
import { CoreUrl } from '@singletons/url';
|
||||||
import { CoreTime } from '@singletons/time';
|
import { CoreTime } from '@singletons/time';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that displays a calendar.
|
* Component that displays a calendar.
|
||||||
|
@ -69,9 +70,9 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
|
||||||
@Input() initialYear?: number; // Initial year to load.
|
@Input() initialYear?: number; // Initial year to load.
|
||||||
@Input() initialMonth?: number; // Initial month to load.
|
@Input() initialMonth?: number; // Initial month to load.
|
||||||
@Input() filter?: AddonCalendarFilter; // Filter to apply.
|
@Input() filter?: AddonCalendarFilter; // Filter to apply.
|
||||||
@Input() hidden?: boolean; // Whether the component is hidden.
|
@Input({ transform: toBoolean }) hidden = false; // Whether the component is hidden.
|
||||||
@Input() canNavigate?: string | boolean; // Whether to include arrows to change the month. Defaults to true.
|
@Input({ transform: toBoolean }) canNavigate = true; // Whether to include arrows to change the month
|
||||||
@Input() displayNavButtons?: string | boolean; // Whether to display nav buttons created by this component. Defaults to true.
|
@Input({ transform: toBoolean }) displayNavButtons = true; // Whether to display nav buttons created by this component.
|
||||||
@Output() onEventClicked = new EventEmitter<number>();
|
@Output() onEventClicked = new EventEmitter<number>();
|
||||||
@Output() onDayClicked = new EventEmitter<{day: number; month: number; year: number}>();
|
@Output() onDayClicked = new EventEmitter<{day: number; month: number; year: number}>();
|
||||||
|
|
||||||
|
@ -145,10 +146,6 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
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({
|
const source = new AddonCalendarMonthSlidesItemsManagerSource(this, moment({
|
||||||
year: this.initialYear,
|
year: this.initialYear,
|
||||||
month: this.initialMonth ? this.initialMonth - 1 : undefined,
|
month: this.initialMonth ? this.initialMonth - 1 : undefined,
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { CoreError } from '@classes/errors/error';
|
||||||
import { CoreModals } from '@services/modals';
|
import { CoreModals } from '@services/modals';
|
||||||
import { AddonModAssignFeedbackCommentsTextData } from '../feedback/comments/services/handler';
|
import { AddonModAssignFeedbackCommentsTextData } from '../feedback/comments/services/handler';
|
||||||
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../services/assign';
|
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../services/assign';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for component to render a feedback plugin.
|
* Base class for component to render a feedback plugin.
|
||||||
|
@ -32,8 +33,8 @@ export class AddonModAssignFeedbackPluginBaseComponent implements IAddonModAssig
|
||||||
@Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
|
@Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
|
||||||
@Input({ required: true }) userId!: number; // The user ID of the submission.
|
@Input({ required: true }) userId!: number; // The user ID of the submission.
|
||||||
@Input() configs?: Record<string,string>; // The configs for the plugin.
|
@Input() configs?: Record<string,string>; // The configs for the plugin.
|
||||||
@Input() canEdit = false; // Whether the user can edit.
|
@Input({ transform: toBoolean }) canEdit = false; // Whether the user can edit.
|
||||||
@Input() edit = false; // Whether the user is editing.
|
@Input({ transform: toBoolean }) edit = false; // Whether the user is editing.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a modal to edit the feedback plugin.
|
* Open a modal to edit the feedback plugin.
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../services/assign';
|
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../services/assign';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for component to render a submission plugin.
|
* Base class for component to render a submission plugin.
|
||||||
|
@ -27,8 +28,8 @@ export class AddonModAssignSubmissionPluginBaseComponent {
|
||||||
@Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
|
@Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
|
||||||
@Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
|
@Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
|
||||||
@Input() configs?: Record<string, string>; // The configs for the plugin.
|
@Input() configs?: Record<string, string>; // The configs for the plugin.
|
||||||
@Input() edit = false; // Whether the user is editing.
|
@Input({ transform: toBoolean }) edit = false; // Whether the user is editing.
|
||||||
@Input() allowOffline = false; // Whether to allow offline.
|
@Input({ transform: toBoolean }) allowOffline = false; // Whether to allow offline.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidate the data.
|
* Invalidate the data.
|
||||||
|
|
|
@ -25,6 +25,7 @@ import {
|
||||||
import { AddonModAssignHelper, AddonModAssignPluginConfig } from '../../services/assign-helper';
|
import { AddonModAssignHelper, AddonModAssignPluginConfig } from '../../services/assign-helper';
|
||||||
import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate';
|
import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate';
|
||||||
import { ADDON_MOD_ASSIGN_COMPONENT } from '../../constants';
|
import { ADDON_MOD_ASSIGN_COMPONENT } from '../../constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that displays an assignment feedback plugin.
|
* Component that displays an assignment feedback plugin.
|
||||||
|
@ -41,8 +42,8 @@ export class AddonModAssignFeedbackPluginComponent implements OnInit {
|
||||||
@Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
|
@Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
|
||||||
@Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
|
@Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
|
||||||
@Input({ required: true }) userId!: number; // The user ID of the submission.
|
@Input({ required: true }) userId!: number; // The user ID of the submission.
|
||||||
@Input() canEdit = false; // Whether the user can edit.
|
@Input({ transform: toBoolean }) canEdit = false; // Whether the user can edit.
|
||||||
@Input() edit = false; // Whether the user is editing.
|
@Input({ transform: toBoolean }) edit = false; // Whether the user is editing.
|
||||||
|
|
||||||
pluginComponent?: Type<IAddonModAssignFeedbackPluginComponent>; // Component to render the plugin.
|
pluginComponent?: Type<IAddonModAssignFeedbackPluginComponent>; // Component to render the plugin.
|
||||||
data?: AddonModAssignFeedbackPluginData; // Data to pass to the component.
|
data?: AddonModAssignFeedbackPluginData; // Data to pass to the component.
|
||||||
|
|
|
@ -25,6 +25,7 @@ import { AddonModAssignSubmissionDelegate } from '../../services/submission-dele
|
||||||
import { CoreFileEntry } from '@services/file-helper';
|
import { CoreFileEntry } from '@services/file-helper';
|
||||||
import type { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
|
import type { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
|
||||||
import { ADDON_MOD_ASSIGN_COMPONENT } from '../../constants';
|
import { ADDON_MOD_ASSIGN_COMPONENT } from '../../constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that displays an assignment submission plugin.
|
* Component that displays an assignment submission plugin.
|
||||||
|
@ -40,8 +41,8 @@ export class AddonModAssignSubmissionPluginComponent implements OnInit {
|
||||||
@Input({ required: true }) assign!: AddonModAssignAssign; // The assignment.
|
@Input({ required: true }) assign!: AddonModAssignAssign; // The assignment.
|
||||||
@Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
|
@Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
|
||||||
@Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
|
@Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
|
||||||
@Input() edit = false; // Whether the user is editing.
|
@Input({ transform: toBoolean }) edit = false; // Whether the user is editing.
|
||||||
@Input() allowOffline = false; // Whether to allow offline.
|
@Input({ transform: toBoolean }) allowOffline = false; // Whether to allow offline.
|
||||||
|
|
||||||
pluginComponent?: Type<AddonModAssignSubmissionPluginBaseComponent>; // Component to render the plugin.
|
pluginComponent?: Type<AddonModAssignSubmissionPluginBaseComponent>; // Component to render the plugin.
|
||||||
data?: AddonModAssignSubmissionPluginData; // Data to pass to the component.
|
data?: AddonModAssignSubmissionPluginData; // Data to pass to the component.
|
||||||
|
|
|
@ -54,6 +54,7 @@ import { CoreDom } from '@singletons/dom';
|
||||||
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
|
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
|
||||||
import { ADDON_MOD_FORUM_CHANGE_DISCUSSION_EVENT, ADDON_MOD_FORUM_COMPONENT } from '../../constants';
|
import { ADDON_MOD_FORUM_CHANGE_DISCUSSION_EVENT, ADDON_MOD_FORUM_COMPONENT } from '../../constants';
|
||||||
import { CoreToasts } from '@services/toasts';
|
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.).
|
* Components that shows a discussion post, its attachments and the action buttons allowed (reply, etc.).
|
||||||
|
@ -73,13 +74,13 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
|
||||||
@Input({ required: true }) componentId!: number; // Component ID.
|
@Input({ required: true }) componentId!: number; // Component ID.
|
||||||
@Input({ required: true }) formData!: AddonModForumSharedPostFormData; // New post data. Usually shared between posts.
|
@Input({ required: true }) formData!: AddonModForumSharedPostFormData; // New post data. Usually shared between posts.
|
||||||
@Input({ required: true }) originalData!: Omit<AddonModForumPostFormData, 'id'>; // Original data. Usually shared between posts.
|
@Input({ required: true }) originalData!: Omit<AddonModForumPostFormData, 'id'>; // Original data. Usually shared between posts.
|
||||||
@Input({ required: true }) trackPosts!: boolean; // True if post is being tracked.
|
@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 }) forum!: AddonModForumData; // The forum the post belongs to.
|
||||||
@Input({ required: true }) accessInfo!: AddonModForumAccessInformation; // Forum access information.
|
@Input({ required: true }) accessInfo!: AddonModForumAccessInformation; // Forum access information.
|
||||||
@Input() parentSubject?: string; // Subject of parent post.
|
@Input() parentSubject?: string; // Subject of parent post.
|
||||||
@Input() ratingInfo?: CoreRatingInfo; // Rating info item.
|
@Input() ratingInfo?: CoreRatingInfo; // Rating info item.
|
||||||
@Input() leavingPage?: boolean; // Whether the page that contains this post is being left and will be destroyed.
|
@Input({ transform: toBoolean }) leavingPage = false; // Whether the page that contains this post is being left.
|
||||||
@Input() highlight = false;
|
@Input({ transform: toBoolean }) highlight = false;
|
||||||
@Output() onPostChange: EventEmitter<void> = new EventEmitter<void>(); // Event emitted when a reply is posted or modified.
|
@Output() onPostChange: EventEmitter<void> = new EventEmitter<void>(); // Event emitted when a reply is posted or modified.
|
||||||
|
|
||||||
@ViewChild('replyFormEl') formElement!: ElementRef;
|
@ViewChild('replyFormEl') formElement!: ElementRef;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
|
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
|
||||||
import { AddonModQuizSync } from '@addons/mod/quiz/services/quiz-sync';
|
import { AddonModQuizSync } from '@addons/mod/quiz/services/quiz-sync';
|
||||||
import { Component, OnInit, Input } from '@angular/core';
|
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() rule?: string; // The name of the rule.
|
||||||
@Input() quiz?: AddonModQuizQuizWSData; // The quiz the rule belongs to.
|
@Input() quiz?: AddonModQuizQuizWSData; // The quiz the rule belongs to.
|
||||||
@Input() attempt?: AddonModQuizAttemptWSData; // The attempt being started/continued.
|
@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() siteId?: string; // Site ID.
|
||||||
@Input() form?: FormGroup; // Form where to add the form control.
|
@Input() form?: FormGroup; // Form where to add the form control.
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { Component, OnInit, Input } from '@angular/core';
|
||||||
import { FormGroup, FormBuilder } from '@angular/forms';
|
import { FormGroup, FormBuilder } from '@angular/forms';
|
||||||
|
|
||||||
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
|
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to render the preflight for password.
|
* 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() rule?: string; // The name of the rule.
|
||||||
@Input() quiz?: AddonModQuizQuizWSData; // The quiz the rule belongs to.
|
@Input() quiz?: AddonModQuizQuizWSData; // The quiz the rule belongs to.
|
||||||
@Input() attempt?: AddonModQuizAttemptWSData; // The attempt being started/continued.
|
@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() siteId?: string; // Site ID.
|
||||||
@Input() form?: FormGroup; // Form where to add the form control.
|
@Input() form?: FormGroup; // Form where to add the form control.
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { FormGroup } from '@angular/forms';
|
||||||
|
|
||||||
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
|
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
|
||||||
import { CoreTime } from '@singletons/time';
|
import { CoreTime } from '@singletons/time';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to render the preflight for time limit.
|
* 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() rule?: string; // The name of the rule.
|
||||||
@Input() quiz?: AddonModQuizQuizWSData; // The quiz the rule belongs to.
|
@Input() quiz?: AddonModQuizQuizWSData; // The quiz the rule belongs to.
|
||||||
@Input() attempt?: AddonModQuizAttemptWSData; // The attempt being started/continued.
|
@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() siteId?: string; // Site ID.
|
||||||
@Input() form?: FormGroup; // Form where to add the form control.
|
@Input() form?: FormGroup; // Form where to add the form control.
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
import { Component, Input, OnChanges } from '@angular/core';
|
import { Component, Input, OnChanges } from '@angular/core';
|
||||||
import { AddonModQuiz } from '../../services/quiz';
|
import { AddonModQuiz } from '../../services/quiz';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that displays an attempt state.
|
* Component that displays an attempt state.
|
||||||
|
@ -26,7 +27,7 @@ import { AddonModQuiz } from '../../services/quiz';
|
||||||
export class AddonModQuizAttemptStateComponent implements OnChanges {
|
export class AddonModQuizAttemptStateComponent implements OnChanges {
|
||||||
|
|
||||||
@Input() state = '';
|
@Input() state = '';
|
||||||
@Input() finishedOffline = false;
|
@Input({ transform: toBoolean }) finishedOffline = false;
|
||||||
|
|
||||||
readableState = '';
|
readableState = '';
|
||||||
color = '';
|
color = '';
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreSharedModule } from '@/core/shared.module';
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
import { CoreQuestionQuestionParsed } from '@features/question/services/question';
|
import { CoreQuestionQuestionParsed } from '@features/question/services/question';
|
||||||
|
@ -32,11 +33,11 @@ import { ModalController } from '@singletons';
|
||||||
export class AddonModQuizNavigationModalComponent {
|
export class AddonModQuizNavigationModalComponent {
|
||||||
|
|
||||||
@Input() navigation?: AddonModQuizNavigationQuestion[]; // Whether the user is reviewing the attempt.
|
@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() nextPage?: number; // Next page.
|
||||||
@Input() currentPage?: number; // Current page.
|
@Input() currentPage?: number; // Current page.
|
||||||
@Input() isReview?: boolean; // Whether the user is reviewing the attempt.
|
@Input({ transform: toBoolean }) isReview = false; // Whether the user is reviewing the attempt.
|
||||||
@Input() isSequential?: boolean; // Whether quiz navigation is sequential.
|
@Input({ transform: toBoolean }) isSequential = false; // Whether quiz navigation is sequential.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close modal.
|
* Close modal.
|
||||||
|
|
|
@ -23,6 +23,7 @@ import { AddonModQuizAccessRuleDelegate } from '../../services/access-rules-dele
|
||||||
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '../../services/quiz';
|
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '../../services/quiz';
|
||||||
import { CoreDom } from '@singletons/dom';
|
import { CoreDom } from '@singletons/dom';
|
||||||
import { CoreSharedModule } from '@/core/shared.module';
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modal that renders the access rules for a quiz.
|
* Modal that renders the access rules for a quiz.
|
||||||
|
@ -42,7 +43,7 @@ export class AddonModQuizPreflightModalComponent implements OnInit {
|
||||||
@Input({ required: true }) title!: string;
|
@Input({ required: true }) title!: string;
|
||||||
@Input() quiz?: AddonModQuizQuizWSData;
|
@Input() quiz?: AddonModQuizQuizWSData;
|
||||||
@Input() attempt?: AddonModQuizAttemptWSData;
|
@Input() attempt?: AddonModQuizAttemptWSData;
|
||||||
@Input() prefetch?: boolean;
|
@Input({ transform: toBoolean }) prefetch = false;
|
||||||
@Input({ required: true }) siteId!: string;
|
@Input({ required: true }) siteId!: string;
|
||||||
@Input({ required: true }) rules!: string[];
|
@Input({ required: true }) rules!: string[];
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { AddonModWorkshopGetAssessmentFormFieldsParsedData } from '../services/workshop';
|
import { AddonModWorkshopGetAssessmentFormFieldsParsedData } from '../services/workshop';
|
||||||
import { AddonModWorkshopSubmissionAssessmentWithFormData } from '../services/workshop-helper';
|
import { AddonModWorkshopSubmissionAssessmentWithFormData } from '../services/workshop-helper';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for component to render an assessment strategy.
|
* Base class for component to render an assessment strategy.
|
||||||
|
@ -26,7 +27,7 @@ export class AddonModWorkshopAssessmentStrategyBaseComponent {
|
||||||
|
|
||||||
@Input({ required: true }) workshopId!: number;
|
@Input({ required: true }) workshopId!: number;
|
||||||
@Input({ required: true }) assessment!: AddonModWorkshopSubmissionAssessmentWithFormData;
|
@Input({ required: true }) assessment!: AddonModWorkshopSubmissionAssessmentWithFormData;
|
||||||
@Input({ required: true }) edit!: boolean;
|
@Input({ required: true, transform: toBoolean }) edit = false;
|
||||||
@Input({ required: true }) selectedValues!: AddonModWorkshopGetAssessmentFormFieldsParsedData[];
|
@Input({ required: true }) selectedValues!: AddonModWorkshopGetAssessmentFormFieldsParsedData[];
|
||||||
@Input({ required: true }) fieldErrors!: Record<string, string>;
|
@Input({ required: true }) fieldErrors!: Record<string, string>;
|
||||||
@Input({ required: true }) strategy!: string;
|
@Input({ required: true }) strategy!: string;
|
||||||
|
|
|
@ -42,6 +42,7 @@ import {
|
||||||
ADDON_MOD_WORKSHOP_COMPONENT,
|
ADDON_MOD_WORKSHOP_COMPONENT,
|
||||||
AddonModWorkshopOverallFeedbackMode,
|
AddonModWorkshopOverallFeedbackMode,
|
||||||
} from '@addons/mod/workshop/constants';
|
} from '@addons/mod/workshop/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that displays workshop assessment strategy form.
|
* Component that displays workshop assessment strategy form.
|
||||||
|
@ -57,7 +58,7 @@ export class AddonModWorkshopAssessmentStrategyComponent implements OnInit, OnDe
|
||||||
@Input({ required: true }) assessmentId!: number;
|
@Input({ required: true }) assessmentId!: number;
|
||||||
@Input({ required: true }) userId!: number;
|
@Input({ required: true }) userId!: number;
|
||||||
@Input({ required: true }) strategy!: string;
|
@Input({ required: true }) strategy!: string;
|
||||||
@Input() edit = false;
|
@Input({ transform: toBoolean }) edit = false;
|
||||||
|
|
||||||
@ViewChild('assessmentForm') formElement!: ElementRef;
|
@ViewChild('assessmentForm') formElement!: ElementRef;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { ModalController } from '@singletons';
|
||||||
import { AddonModWorkshopPhaseData, AddonModWorkshopPhaseTaskData } from '../../services/workshop';
|
import { AddonModWorkshopPhaseData, AddonModWorkshopPhaseTaskData } from '../../services/workshop';
|
||||||
import { AddonModWorkshopPhase } from '../../constants';
|
import { AddonModWorkshopPhase } from '../../constants';
|
||||||
import { CoreSharedModule } from '@/core/shared.module';
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays the phase info modal.
|
* Page that displays the phase info modal.
|
||||||
|
@ -33,7 +34,7 @@ export class AddonModWorkshopPhaseInfoModalComponent implements OnInit {
|
||||||
|
|
||||||
@Input({ required: true }) phases!: AddonModWorkshopPhaseDataWithSwitch[];
|
@Input({ required: true }) phases!: AddonModWorkshopPhaseDataWithSwitch[];
|
||||||
@Input({ required: true }) workshopPhase!: AddonModWorkshopPhase;
|
@Input({ required: true }) workshopPhase!: AddonModWorkshopPhase;
|
||||||
@Input() showSubmit = false;
|
@Input({ transform: toBoolean }) showSubmit = false;
|
||||||
@Input({ required: true }) externalUrl!: string;
|
@Input({ required: true }) externalUrl!: string;
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|
|
@ -30,6 +30,7 @@ import {
|
||||||
} from '../../services/workshop-helper';
|
} from '../../services/workshop-helper';
|
||||||
import { AddonModWorkshopOffline } from '../../services/workshop-offline';
|
import { AddonModWorkshopOffline } from '../../services/workshop-offline';
|
||||||
import { ADDON_MOD_WORKSHOP_COMPONENT, ADDON_MOD_WORKSHOP_PAGE_NAME, AddonModWorkshopPhase } from '@addons/mod/workshop/constants';
|
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.
|
* Component that displays workshop submission.
|
||||||
|
@ -47,7 +48,7 @@ export class AddonModWorkshopSubmissionComponent implements OnInit {
|
||||||
@Input({ required: true }) access!: AddonModWorkshopGetWorkshopAccessInformationWSResponse;
|
@Input({ required: true }) access!: AddonModWorkshopGetWorkshopAccessInformationWSResponse;
|
||||||
@Input({ required: true }) courseId!: number;
|
@Input({ required: true }) courseId!: number;
|
||||||
@Input() assessment?: AddonModWorkshopSubmissionAssessmentWithFormData;
|
@Input() assessment?: AddonModWorkshopSubmissionAssessmentWithFormData;
|
||||||
@Input() summary = false;
|
@Input({ transform: toBoolean }) summary = false;
|
||||||
|
|
||||||
component = ADDON_MOD_WORKSHOP_COMPONENT;
|
component = ADDON_MOD_WORKSHOP_COMPONENT;
|
||||||
componentId?: number;
|
componentId?: number;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { ContextLevel } from '@/core/constants';
|
import { ContextLevel } from '@/core/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||||
|
|
||||||
import { CoreQuestionBehaviourButton, CoreQuestionQuestion } from '@features/question/services/question-helper';
|
import { CoreQuestionBehaviourButton, CoreQuestionQuestion } from '@features/question/services/question-helper';
|
||||||
|
@ -30,11 +31,11 @@ export class AddonQbehaviourDeferredCBMComponent {
|
||||||
@Input() component?: string; // The component the question belongs to.
|
@Input() component?: string; // The component the question belongs to.
|
||||||
@Input() componentId?: number; // ID of the component the question belongs to.
|
@Input() componentId?: number; // ID of the component the question belongs to.
|
||||||
@Input() attemptId?: number; // Attempt ID.
|
@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() contextLevel?: ContextLevel; // The context level.
|
||||||
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
||||||
@Input() courseId?: number; // Course ID the question belongs to (if any). It can be used to improve performance with filters.
|
@Input() 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.
|
@Input() preferredBehaviour?: string; // Preferred behaviour.
|
||||||
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
|
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
|
||||||
@Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
|
@Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { ContextLevel } from '@/core/constants';
|
import { ContextLevel } from '@/core/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||||
|
|
||||||
import { CoreQuestionBehaviourButton, CoreQuestionQuestion } from '@features/question/services/question-helper';
|
import { CoreQuestionBehaviourButton, CoreQuestionQuestion } from '@features/question/services/question-helper';
|
||||||
|
@ -30,11 +31,11 @@ export class AddonQbehaviourInformationItemComponent {
|
||||||
@Input() component?: string; // The component the question belongs to.
|
@Input() component?: string; // The component the question belongs to.
|
||||||
@Input() componentId?: number; // ID of the component the question belongs to.
|
@Input() componentId?: number; // ID of the component the question belongs to.
|
||||||
@Input() attemptId?: number; // Attempt ID.
|
@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() contextLevel?: ContextLevel; // The context level.
|
||||||
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
||||||
@Input() courseId?: number; // Course ID the question belongs to (if any). It can be used to improve performance with filters.
|
@Input() 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.
|
@Input() preferredBehaviour?: string; // Preferred behaviour.
|
||||||
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
|
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
|
||||||
@Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
|
@Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
|
||||||
|
|
|
@ -39,6 +39,7 @@ import { CoreDirectivesRegistry } from '@singletons/directives-registry';
|
||||||
import { Swiper } from 'swiper';
|
import { Swiper } from 'swiper';
|
||||||
import { SwiperOptions } from 'swiper/types';
|
import { SwiperOptions } from 'swiper/types';
|
||||||
import { CoreSwiper } from '@singletons/swiper';
|
import { CoreSwiper } from '@singletons/swiper';
|
||||||
|
import { toBoolean } from '../transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to abstract some common code for tabs.
|
* Class to abstract some common code for tabs.
|
||||||
|
@ -52,7 +53,7 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements AfterViewIn
|
||||||
protected static readonly MIN_TAB_WIDTH = 107;
|
protected static readonly MIN_TAB_WIDTH = 107;
|
||||||
|
|
||||||
@Input() selectedIndex = 0; // Index of the tab to select.
|
@Input() selectedIndex = 0; // Index of the tab to select.
|
||||||
@Input() hideUntil = false; // Determine when should the contents be shown.
|
@Input({ transform: toBoolean }) hideUntil = false; // Determine when should the contents be shown.
|
||||||
@Output() protected ionChange = new EventEmitter<T>(); // Emitted when the tab changes.
|
@Output() protected ionChange = new EventEmitter<T>(); // Emitted when the tab changes.
|
||||||
|
|
||||||
protected swiper?: Swiper;
|
protected swiper?: Swiper;
|
||||||
|
|
|
@ -25,6 +25,7 @@ import { CoreFileUploaderHelper } from '@features/fileuploader/services/fileuplo
|
||||||
import { CoreFileEntry } from '@services/file-helper';
|
import { CoreFileEntry } from '@services/file-helper';
|
||||||
import { CoreCourses } from '@features/courses/services/courses';
|
import { CoreCourses } from '@features/courses/services/courses';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to render attachments, allow adding more and delete the current ones.
|
* Component to render attachments, allow adding more and delete the current ones.
|
||||||
|
@ -51,9 +52,9 @@ export class CoreAttachmentsComponent implements OnInit {
|
||||||
@Input() maxSubmissions?: number; // Max number of attachments. -1 means unlimited, not defined means unknown limit.
|
@Input() maxSubmissions?: number; // Max number of attachments. -1 means unlimited, not defined means unknown limit.
|
||||||
@Input() component?: string; // Component the downloaded files will be linked to.
|
@Input() component?: string; // Component the downloaded files will be linked to.
|
||||||
@Input() componentId?: string | number; // Component ID.
|
@Input() componentId?: string | number; // Component ID.
|
||||||
@Input() allowOffline?: boolean | string; // Whether to allow selecting files in offline.
|
@Input({ transform: toBoolean }) allowOffline = false; // Whether to allow selecting files in offline.
|
||||||
@Input() acceptedTypes?: string; // List of supported filetypes. If undefined, all types supported.
|
@Input() acceptedTypes?: string; // List of supported filetypes. If undefined, all types supported.
|
||||||
@Input() required?: boolean; // Whether to display the required mark.
|
@Input({ transform: toBoolean }) required = false; // Whether to display the required mark.
|
||||||
@Input() courseId?: number; // Course ID.
|
@Input() courseId?: number; // Course ID.
|
||||||
@Input() title = Translate.instant('core.fileuploader.attachedfiles'); // Title to display.
|
@Input() title = Translate.instant('core.fileuploader.attachedfiles'); // Title to display.
|
||||||
|
|
||||||
|
@ -131,9 +132,7 @@ export class CoreAttachmentsComponent implements OnInit {
|
||||||
* Add a new attachment.
|
* Add a new attachment.
|
||||||
*/
|
*/
|
||||||
async add(): Promise<void> {
|
async add(): Promise<void> {
|
||||||
const allowOffline = !!this.allowOffline && this.allowOffline !== 'false';
|
if (!this.allowOffline && !CoreNetwork.isOnline()) {
|
||||||
|
|
||||||
if (!allowOffline && !CoreNetwork.isOnline()) {
|
|
||||||
CoreDomUtils.showErrorModal('core.fileuploader.errormustbeonlinetoupload', true);
|
CoreDomUtils.showErrorModal('core.fileuploader.errormustbeonlinetoupload', true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -142,7 +141,7 @@ export class CoreAttachmentsComponent implements OnInit {
|
||||||
const mimetypes = this.fileTypes && this.fileTypes.mimetypes;
|
const mimetypes = this.fileTypes && this.fileTypes.mimetypes;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await CoreFileUploaderHelper.selectFile(this.maxSize, allowOffline, undefined, mimetypes);
|
const result = await CoreFileUploaderHelper.selectFile(this.maxSize, this.allowOffline, undefined, mimetypes);
|
||||||
|
|
||||||
this.files?.push(result);
|
this.files?.push(result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,6 +25,6 @@ import { Component, Input } from '@angular/core';
|
||||||
export class CoreBSTooltipComponent {
|
export class CoreBSTooltipComponent {
|
||||||
|
|
||||||
@Input() content = '';
|
@Input() content = '';
|
||||||
@Input() html?: boolean;
|
@Input({ transform: toBoolean }) html = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { CoreAnimations } from '@components/animations';
|
import { CoreAnimations } from '@components/animations';
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ import { CoreAnimations } from '@components/animations';
|
||||||
})
|
})
|
||||||
export class CoreButtonWithSpinnerComponent {
|
export class CoreButtonWithSpinnerComponent {
|
||||||
|
|
||||||
@Input() loading = true;
|
@Input({ transform: toBoolean }) loading = true;
|
||||||
@Input() loadingLabel = 'core.loading';
|
@Input() loadingLabel = 'core.loading';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { ContextLevel } from '@/core/constants';
|
import { ContextLevel } from '@/core/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input, OnDestroy, OnInit, ElementRef, OnChanges, ViewChild, SimpleChange } from '@angular/core';
|
import { Component, Input, OnDestroy, OnInit, ElementRef, OnChanges, ViewChild, SimpleChange } from '@angular/core';
|
||||||
import { CoreFilter } from '@features/filter/services/filter';
|
import { CoreFilter } from '@features/filter/services/filter';
|
||||||
import { CoreFilterHelper } from '@features/filter/services/filter-helper';
|
import { CoreFilterHelper } from '@features/filter/services/filter-helper';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
|
||||||
import { ChartLegendLabelItem, ChartLegendOptions } from 'chart.js';
|
import { ChartLegendLabelItem, ChartLegendOptions } from 'chart.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,11 +50,12 @@ export class CoreChartComponent implements OnDestroy, OnInit, OnChanges {
|
||||||
@Input() type?: string; // Type of chart.
|
@Input() type?: string; // Type of chart.
|
||||||
@Input() legend?: ChartLegendOptions; // Legend options.
|
@Input() legend?: ChartLegendOptions; // Legend options.
|
||||||
@Input() height = 300; // Height of the chart element.
|
@Input() height = 300; // Height of the chart element.
|
||||||
@Input() filter?: boolean | string; // Whether to filter labels. If not defined, true if contextLevel and instanceId are set.
|
@Input({ transform: toBoolean }) filter?: boolean; // Whether to filter labels.
|
||||||
|
// If not defined, true if contextLevel and instanceId are set.
|
||||||
@Input() contextLevel?: ContextLevel; // The context level of the text.
|
@Input() contextLevel?: ContextLevel; // The context level of the text.
|
||||||
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
||||||
@Input() courseId?: number; // Course ID the text belongs to. It can be used to improve performance with filters.
|
@Input() courseId?: number; // Course ID the text belongs to. It can be used to improve performance with filters.
|
||||||
@Input() wsNotFiltered?: boolean | string; // If true it means the WS didn't filter the labels for some reason.
|
@Input({ transform: toBoolean }) wsNotFiltered = false; // If true it means the WS didn't filter the labels for some reason.
|
||||||
@ViewChild('canvas') canvas?: ElementRef<HTMLCanvasElement>;
|
@ViewChild('canvas') canvas?: ElementRef<HTMLCanvasElement>;
|
||||||
|
|
||||||
chart?: ChartWithLegend;
|
chart?: ChartWithLegend;
|
||||||
|
@ -158,7 +159,7 @@ export class CoreChartComponent implements OnDestroy, OnInit, OnChanges {
|
||||||
clean: true,
|
clean: true,
|
||||||
singleLine: true,
|
singleLine: true,
|
||||||
courseId: this.courseId,
|
courseId: this.courseId,
|
||||||
wsNotFiltered: CoreUtils.isTrueOrOne(this.wsNotFiltered),
|
wsNotFiltered: this.wsNotFiltered,
|
||||||
};
|
};
|
||||||
|
|
||||||
const filters = await CoreFilterHelper.getFilters(this.contextLevel, this.contextInstanceId, options);
|
const filters = await CoreFilterHelper.getFilters(this.contextLevel, this.contextInstanceId, options);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
Input,
|
Input,
|
||||||
|
@ -42,11 +43,11 @@ import {
|
||||||
})
|
})
|
||||||
export class CoreChronoComponent implements OnInit, OnChanges, OnDestroy {
|
export class CoreChronoComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
@Input() running?: boolean; // Set it to true to start the chrono. Set it to false to stop it.
|
@Input({ transform: toBoolean }) running = false; // Set it to true to start the chrono. Set it to false to stop it.
|
||||||
@Input() startTime = 0; // Number of milliseconds to put in the chrono before starting.
|
@Input() startTime = 0; // Number of milliseconds to put in the chrono before starting.
|
||||||
@Input() endTime?: number; // Number of milliseconds to stop the chrono.
|
@Input() endTime?: number; // Number of milliseconds to stop the chrono.
|
||||||
@Input() reset?: boolean; // Set it to true to reset the chrono.
|
@Input({ transform: toBoolean }) reset = false; // Set it to true to reset the chrono.
|
||||||
@Input() hours = true;
|
@Input({ transform: toBoolean }) hours = true;
|
||||||
@Output() onEnd: EventEmitter<void>; // Will emit an event when the endTime is reached.
|
@Output() onEnd: EventEmitter<void>; // Will emit an event when the endTime is reached.
|
||||||
|
|
||||||
time = 0;
|
time = 0;
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { Translate } from '@singletons';
|
||||||
import { ModalOptions } from '@ionic/core';
|
import { ModalOptions } from '@ionic/core';
|
||||||
import { CoreModals } from '@services/modals';
|
import { CoreModals } from '@services/modals';
|
||||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that show a combo select button (combobox).
|
* Component that show a combo select button (combobox).
|
||||||
|
@ -52,7 +53,7 @@ export class CoreComboboxComponent implements ControlValueAccessor {
|
||||||
|
|
||||||
@Input() interface: 'popover' | 'modal' = 'popover';
|
@Input() interface: 'popover' | 'modal' = 'popover';
|
||||||
@Input() label = Translate.instant('core.show'); // Aria label.
|
@Input() label = Translate.instant('core.show'); // Aria label.
|
||||||
@Input() disabled = false;
|
@Input({ transform: toBoolean }) disabled = false;
|
||||||
@Input() selection = '';
|
@Input() selection = '';
|
||||||
@Output() onChange = new EventEmitter<unknown>(); // Will emit an event the value changed.
|
@Output() onChange = new EventEmitter<unknown>(); // Will emit an event the value changed.
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
import { Component, Input, Output, OnInit, OnDestroy, EventEmitter, OnChanges, SimpleChange } from '@angular/core';
|
import { Component, Input, Output, OnInit, OnDestroy, EventEmitter, OnChanges, SimpleChange } from '@angular/core';
|
||||||
import { CoreContextMenuComponent } from '../context-menu/context-menu';
|
import { CoreContextMenuComponent } from '../context-menu/context-menu';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This directive adds a item to the Context Menu popover.
|
* This directive adds a item to the Context Menu popover.
|
||||||
|
@ -40,19 +41,19 @@ export class CoreContextMenuItemComponent implements OnInit, OnDestroy, OnChange
|
||||||
// If is "toggle" a toggle switch will be shown.
|
// If is "toggle" a toggle switch will be shown.
|
||||||
// If no icon or spinner is selected, no action or link will work.
|
// If no icon or spinner is selected, no action or link will work.
|
||||||
// If href but no iconAction is provided arrow-right will be used.
|
// If href but no iconAction is provided arrow-right will be used.
|
||||||
@Input() iconSlash?: boolean; // Display a red slash over the icon.
|
@Input({ transform: toBoolean }) iconSlash = false; // Display a red slash over the icon.
|
||||||
@Input() ariaAction?: string; // Aria label to add to iconAction. If not set, it will be equal to content.
|
@Input() ariaAction?: string; // Aria label to add to iconAction. If not set, it will be equal to content.
|
||||||
@Input() href?: string; // Link to go if no action provided.
|
@Input() href?: string; // Link to go if no action provided.
|
||||||
@Input() captureLink?: boolean | string; // Whether the link needs to be captured by the app.
|
@Input({ transform: toBoolean }) captureLink = false; // Whether the link needs to be captured by the app.
|
||||||
@Input() autoLogin: boolean | string = true; // Whether the link needs to be opened using auto-login.
|
@Input({ transform: toBoolean }) autoLogin = true; // Whether the link needs to be opened using auto-login.
|
||||||
@Input() closeOnClick = true; // Whether to close the popover when the item is clicked.
|
@Input({ transform: toBoolean }) closeOnClick = true; // Whether to close the popover when the item is clicked.
|
||||||
@Input() priority?: number; // Used to sort items. The highest priority, the highest position.
|
@Input() priority?: number; // Used to sort items. The highest priority, the highest position.
|
||||||
@Input() badge?: string; // A badge to show in the item.
|
@Input() badge?: string; // A badge to show in the item.
|
||||||
@Input() badgeClass?: number; // A class to set in the badge.
|
@Input() badgeClass?: number; // A class to set in the badge.
|
||||||
@Input() badgeA11yText?: string; // Description for the badge, if needed.
|
@Input() badgeA11yText?: string; // Description for the badge, if needed.
|
||||||
@Input() hidden?: boolean; // Whether the item should be hidden.
|
@Input({ transform: toBoolean }) hidden = false; // Whether the item should be hidden.
|
||||||
@Input() showBrowserWarning = true; // Whether to show a warning before opening browser (for links). Defaults to true.
|
@Input({ transform: toBoolean }) showBrowserWarning = true; // Whether to show a warning before opening browser (for links).
|
||||||
@Input() toggle = false; // Whether the toggle is on or off.
|
@Input({ transform: toBoolean }) toggle = false; // Whether the toggle is on or off.
|
||||||
@Output() action?: EventEmitter<() => void>; // Will emit an event when the item clicked.
|
@Output() action?: EventEmitter<() => void>; // Will emit an event when the item clicked.
|
||||||
@Output() onClosed?: EventEmitter<() => void>; // Will emit an event when the popover is closed because the item was clicked.
|
@Output() onClosed?: EventEmitter<() => void>; // Will emit an event when the popover is closed because the item was clicked.
|
||||||
@Output() toggleChange = new EventEmitter<boolean>();// Will emit an event when toggle changes to enable 2-way data binding.
|
@Output() toggleChange = new EventEmitter<boolean>();// Will emit an event when toggle changes to enable 2-way data binding.
|
||||||
|
@ -94,10 +95,6 @@ export class CoreContextMenuItemComponent implements OnInit, OnDestroy, OnChange
|
||||||
* @param event Event.
|
* @param event Event.
|
||||||
*/
|
*/
|
||||||
toggleChanged(event: Event): void {
|
toggleChanged(event: Event): void {
|
||||||
if (this.toggle === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
this.toggleChange.emit(this.toggle);
|
this.toggleChange.emit(this.toggle);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input, ElementRef, OnInit, OnChanges, HostBinding } from '@angular/core';
|
import { Component, Input, ElementRef, OnInit, OnChanges, HostBinding } from '@angular/core';
|
||||||
import { CoreCourseListItem } from '@features/courses/services/courses';
|
import { CoreCourseListItem } from '@features/courses/services/courses';
|
||||||
import { CoreCoursesHelper } from '@features/courses/services/courses-helper';
|
import { CoreCoursesHelper } from '@features/courses/services/courses-helper';
|
||||||
|
@ -25,7 +26,7 @@ import { CoreColors } from '@singletons/colors';
|
||||||
export class CoreCourseImageComponent implements OnInit, OnChanges {
|
export class CoreCourseImageComponent implements OnInit, OnChanges {
|
||||||
|
|
||||||
@Input({ required: true }) course!: CoreCourseListItem;
|
@Input({ required: true }) course!: CoreCourseListItem;
|
||||||
@Input() fill = false;
|
@Input({ transform: toBoolean }) fill = false;
|
||||||
|
|
||||||
protected element: HTMLElement;
|
protected element: HTMLElement;
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
|
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
|
||||||
import { DownloadStatus } from '@/core/constants';
|
import { DownloadStatus } from '@/core/constants';
|
||||||
import { CoreAnimations } from '@components/animations';
|
import { CoreAnimations } from '@components/animations';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to show a download button with refresh option, the spinner and the status of it.
|
* Component to show a download button with refresh option, the spinner and the status of it.
|
||||||
|
@ -34,9 +35,9 @@ export class CoreDownloadRefreshComponent implements OnInit {
|
||||||
@Input() status?: DownloadStatus; // Download status.
|
@Input() status?: DownloadStatus; // Download status.
|
||||||
@Input() statusesTranslatable?: Partial<CoreDownloadStatusTranslatable>; // Download statuses translatable strings.
|
@Input() statusesTranslatable?: Partial<CoreDownloadStatusTranslatable>; // Download statuses translatable strings.
|
||||||
@Input() statusSubject = ''; // Status subject to use on name filed in the translatable string.
|
@Input() statusSubject = ''; // Status subject to use on name filed in the translatable string.
|
||||||
@Input() enabled = false; // Whether the download is enabled.
|
@Input({ transform: toBoolean }) enabled = false; // Whether the download is enabled.
|
||||||
@Input() loading = true; // Force loading status when is not downloading.
|
@Input({ transform: toBoolean }) loading = true; // Force loading status when is not downloading.
|
||||||
@Input() canTrustDownload = false; // If false, refresh will be shown if downloaded.
|
@Input({ transform: toBoolean }) canTrustDownload = false; // If false, refresh will be shown if downloaded.
|
||||||
@Output() action: EventEmitter<boolean>; // Will emit an event when the item clicked.
|
@Output() action: EventEmitter<boolean>; // Will emit an event when the item clicked.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, HostBinding, Input } from '@angular/core';
|
import { Component, HostBinding, Input } from '@angular/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,13 +31,13 @@ import { Component, HostBinding, Input } from '@angular/core';
|
||||||
export class CoreEmptyBoxComponent {
|
export class CoreEmptyBoxComponent {
|
||||||
|
|
||||||
@Input() message = ''; // Message to display.
|
@Input() message = ''; // Message to display.
|
||||||
@Input() dimmed = false; // Wether the box is dimmed or not.
|
@Input({ transform: toBoolean }) dimmed = false; // Wether the box is dimmed or not.
|
||||||
@Input() icon?: string; // Name of the icon to use.
|
@Input() icon?: string; // Name of the icon to use.
|
||||||
@Input() image?: string; // Image source. If an icon is provided, image won't be used.
|
@Input() image?: string; // Image source. If an icon is provided, image won't be used.
|
||||||
/**
|
/**
|
||||||
* @deprecated since 4.4. Not used anymore.
|
* @deprecated since 4.4. Not used anymore.
|
||||||
*/
|
*/
|
||||||
@Input() flipIconRtl = false;
|
@Input({ transform: toBoolean }) flipIconRtl = false;
|
||||||
|
|
||||||
@HostBinding('class.dimmed')
|
@HostBinding('class.dimmed')
|
||||||
get isDimmed(): boolean {
|
get isDimmed(): boolean {
|
||||||
|
|
|
@ -27,6 +27,7 @@ import { DownloadStatus } from '@/core/constants';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
import { CoreWSFile } from '@services/ws';
|
import { CoreWSFile } from '@services/ws';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to handle a remote file. Shows the file name, icon (depending on mimetype) and a button
|
* Component to handle a remote file. Shows the file name, icon (depending on mimetype) and a button
|
||||||
|
@ -41,11 +42,11 @@ export class CoreFileComponent implements OnInit, OnDestroy {
|
||||||
@Input() file?: CoreWSFile; // The file.
|
@Input() file?: CoreWSFile; // The file.
|
||||||
@Input() component?: string; // Component the file belongs to.
|
@Input() component?: string; // Component the file belongs to.
|
||||||
@Input() componentId?: string | number; // Component ID.
|
@Input() componentId?: string | number; // Component ID.
|
||||||
@Input() canDelete?: boolean | string; // Whether file can be deleted.
|
@Input({ transform: toBoolean }) canDelete = false; // Whether file can be deleted.
|
||||||
@Input() alwaysDownload?: boolean | string; // Whether it should always display the refresh button when the file is downloaded.
|
@Input({ transform: toBoolean }) alwaysDownload = false; // True to always display the refresh button when file is downloaded.
|
||||||
@Input() canDownload?: boolean | string = true; // Whether file can be downloaded.
|
@Input({ transform: toBoolean }) canDownload = true; // Whether file can be downloaded.
|
||||||
@Input() showSize?: boolean | string = true; // Whether show filesize.
|
@Input({ transform: toBoolean }) showSize = true; // Whether show filesize.
|
||||||
@Input() showTime?: boolean | string = true; // Whether show file time modified.
|
@Input({ transform: toBoolean }) showTime = true; // Whether show file time modified.
|
||||||
@Output() onDelete: EventEmitter<void>; // Will notify when the delete button is clicked.
|
@Output() onDelete: EventEmitter<void>; // Will notify when the delete button is clicked.
|
||||||
|
|
||||||
isDownloading?: boolean;
|
isDownloading?: boolean;
|
||||||
|
@ -77,10 +78,6 @@ export class CoreFileComponent implements OnInit, OnDestroy {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.canDelete = CoreUtils.isTrueOrOne(this.canDelete);
|
|
||||||
this.alwaysDownload = CoreUtils.isTrueOrOne(this.alwaysDownload);
|
|
||||||
this.canDownload = CoreUtils.isTrueOrOne(this.canDownload);
|
|
||||||
|
|
||||||
this.fileUrl = CoreFileHelper.getFileUrl(this.file);
|
this.fileUrl = CoreFileHelper.getFileUrl(this.file);
|
||||||
this.timemodified = this.file.timemodified || 0;
|
this.timemodified = this.file.timemodified || 0;
|
||||||
this.siteId = CoreSites.getCurrentSiteId();
|
this.siteId = CoreSites.getCurrentSiteId();
|
||||||
|
@ -92,11 +89,11 @@ export class CoreFileComponent implements OnInit, OnDestroy {
|
||||||
this.openButtonIcon = this.defaultIsOpenWithPicker ? 'fas-file' : 'fas-share-from-square';
|
this.openButtonIcon = this.defaultIsOpenWithPicker ? 'fas-file' : 'fas-share-from-square';
|
||||||
this.openButtonLabel = this.defaultIsOpenWithPicker ? 'core.openfile' : 'core.openwith';
|
this.openButtonLabel = this.defaultIsOpenWithPicker ? 'core.openfile' : 'core.openwith';
|
||||||
|
|
||||||
if (CoreUtils.isTrueOrOne(this.showSize) && this.fileSize && this.fileSize >= 0) {
|
if (this.showSize && this.fileSize && this.fileSize >= 0) {
|
||||||
this.fileSizeReadable = CoreTextUtils.bytesToSize(this.fileSize, 2);
|
this.fileSizeReadable = CoreTextUtils.bytesToSize(this.fileSize, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.showTime = CoreUtils.isTrueOrOne(this.showTime) && this.timemodified > 0;
|
this.showTime = this.showTime && this.timemodified > 0;
|
||||||
|
|
||||||
if ('isexternalfile' in this.file && this.file.isexternalfile) {
|
if ('isexternalfile' in this.file && this.file.isexternalfile) {
|
||||||
this.alwaysDownload = true; // Always show the download button in external files.
|
this.alwaysDownload = true; // Always show the download button in external files.
|
||||||
|
|
|
@ -12,11 +12,11 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input, OnInit, DoCheck, KeyValueDiffers } from '@angular/core';
|
import { Component, Input, OnInit, DoCheck, KeyValueDiffers } from '@angular/core';
|
||||||
import { CoreFileEntry } from '@services/file-helper';
|
import { CoreFileEntry } from '@services/file-helper';
|
||||||
|
|
||||||
import { CoreMimetypeUtils } from '@services/utils/mimetype';
|
import { CoreMimetypeUtils } from '@services/utils/mimetype';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to render a file list.
|
* Component to render a file list.
|
||||||
|
@ -33,11 +33,11 @@ export class CoreFilesComponent implements OnInit, DoCheck {
|
||||||
@Input() files: CoreFileEntry[] = []; // List of files.
|
@Input() files: CoreFileEntry[] = []; // List of files.
|
||||||
@Input() component?: string; // Component the downloaded files will be linked to.
|
@Input() component?: string; // Component the downloaded files will be linked to.
|
||||||
@Input() componentId?: string | number; // Component ID.
|
@Input() componentId?: string | number; // Component ID.
|
||||||
@Input() alwaysDownload?: boolean | string; // Whether it should always display the refresh button when the file is downloaded.
|
@Input({ transform: toBoolean }) alwaysDownload = false; // True to always display the refresh button when file is downloaded.
|
||||||
@Input() canDownload?: boolean | string = true; // Whether file can be downloaded.
|
@Input({ transform: toBoolean }) canDownload = true; // Whether file can be downloaded.
|
||||||
@Input() showSize?: boolean | string = true; // Whether show filesize.
|
@Input({ transform: toBoolean }) showSize = true; // Whether show filesize.
|
||||||
@Input() showTime?: boolean | string = true; // Whether show file time modified.
|
@Input({ transform: toBoolean }) showTime = true; // Whether show file time modified.
|
||||||
@Input() showInline = false; // If true, it will reorder and try to show inline files first.
|
@Input({ transform: toBoolean }) showInline = false; // If true, it will reorder and try to show inline files first.
|
||||||
@Input() extraHtml?: string[]; // Extra HTML for each attachment. Each HTML should be at the same position as the attachment.
|
@Input() extraHtml?: string[]; // Extra HTML for each attachment. Each HTML should be at the same position as the attachment.
|
||||||
|
|
||||||
contentText?: string;
|
contentText?: string;
|
||||||
|
@ -53,7 +53,7 @@ export class CoreFilesComponent implements OnInit, DoCheck {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (CoreUtils.isTrueOrOne(this.showInline) && this.files) {
|
if (this.showInline && this.files) {
|
||||||
this.renderInlineFiles();
|
this.renderInlineFiles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ export class CoreFilesComponent implements OnInit, DoCheck {
|
||||||
* Detect and act upon changes that Angular can’t or won’t detect on its own (objects and arrays).
|
* Detect and act upon changes that Angular can’t or won’t detect on its own (objects and arrays).
|
||||||
*/
|
*/
|
||||||
ngDoCheck(): void {
|
ngDoCheck(): void {
|
||||||
if (CoreUtils.isTrueOrOne(this.showInline) && this.files) {
|
if (this.showInline && this.files) {
|
||||||
// Check if there's any change in the files array.
|
// Check if there's any change in the files array.
|
||||||
const changes = this.differ.diff(this.files);
|
const changes = this.differ.diff(this.files);
|
||||||
if (changes) {
|
if (changes) {
|
||||||
|
|
|
@ -21,7 +21,6 @@ import { CoreFile } from '@services/file';
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreUrl } from '@singletons/url';
|
import { CoreUrl } from '@singletons/url';
|
||||||
import { CoreIframeUtils } from '@services/utils/iframe';
|
import { CoreIframeUtils } from '@services/utils/iframe';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
|
||||||
import { DomSanitizer, Router, StatusBar } from '@singletons';
|
import { DomSanitizer, Router, StatusBar } from '@singletons';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
import { CoreScreen, CoreScreenOrientation } from '@services/screen';
|
import { CoreScreen, CoreScreenOrientation } from '@services/screen';
|
||||||
|
@ -29,6 +28,7 @@ import { Subscription } from 'rxjs';
|
||||||
import { filter } from 'rxjs/operators';
|
import { filter } from 'rxjs/operators';
|
||||||
import { NavigationStart } from '@angular/router';
|
import { NavigationStart } from '@angular/router';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'core-iframe',
|
selector: 'core-iframe',
|
||||||
|
@ -49,10 +49,10 @@ export class CoreIframeComponent implements OnChanges, OnDestroy {
|
||||||
@Input() id: string | null = null;
|
@Input() id: string | null = null;
|
||||||
@Input() iframeWidth = '100%';
|
@Input() iframeWidth = '100%';
|
||||||
@Input() iframeHeight = '100%';
|
@Input() iframeHeight = '100%';
|
||||||
@Input() allowFullscreen?: boolean | string;
|
@Input({ transform: toBoolean }) allowFullscreen = false;
|
||||||
@Input() showFullscreenOnToolbar?: boolean | string;
|
@Input({ transform: toBoolean }) showFullscreenOnToolbar = false;
|
||||||
@Input() autoFullscreenOnRotate?: boolean | string;
|
@Input({ transform: toBoolean }) autoFullscreenOnRotate = false;
|
||||||
@Input() allowAutoLogin = true;
|
@Input({ transform: toBoolean }) allowAutoLogin = true;
|
||||||
@Output() loaded: EventEmitter<HTMLIFrameElement> = new EventEmitter<HTMLIFrameElement>();
|
@Output() loaded: EventEmitter<HTMLIFrameElement> = new EventEmitter<HTMLIFrameElement>();
|
||||||
|
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
|
@ -167,15 +167,6 @@ export class CoreIframeComponent implements OnChanges, OnDestroy {
|
||||||
if (changes.iframeHeight) {
|
if (changes.iframeHeight) {
|
||||||
this.iframeHeight = (this.iframeHeight && CoreDomUtils.formatPixelsSize(this.iframeHeight)) || '100%';
|
this.iframeHeight = (this.iframeHeight && CoreDomUtils.formatPixelsSize(this.iframeHeight)) || '100%';
|
||||||
}
|
}
|
||||||
if (changes.allowFullscreen) {
|
|
||||||
this.allowFullscreen = CoreUtils.isTrueOrOne(this.allowFullscreen);
|
|
||||||
}
|
|
||||||
if (changes.showFullscreenOnToolbar) {
|
|
||||||
this.showFullscreenOnToolbar = CoreUtils.isTrueOrOne(this.showFullscreenOnToolbar);
|
|
||||||
}
|
|
||||||
if (changes.autoFullscreenOnRotate) {
|
|
||||||
this.autoFullscreenOnRotate = CoreUtils.isTrueOrOne(this.autoFullscreenOnRotate);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!changes.src) {
|
if (!changes.src) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input, Output, EventEmitter, OnChanges, SimpleChange, ViewChild, ElementRef } from '@angular/core';
|
import { Component, Input, Output, EventEmitter, OnChanges, SimpleChange, ViewChild, ElementRef } from '@angular/core';
|
||||||
import { IonInfiniteScroll } from '@ionic/angular';
|
import { IonInfiniteScroll } from '@ionic/angular';
|
||||||
import { CoreWait } from '@singletons/wait';
|
import { CoreWait } from '@singletons/wait';
|
||||||
|
@ -30,8 +31,8 @@ const THRESHOLD = .15; // % of the scroll element height that must be close to t
|
||||||
})
|
})
|
||||||
export class CoreInfiniteLoadingComponent implements OnChanges {
|
export class CoreInfiniteLoadingComponent implements OnChanges {
|
||||||
|
|
||||||
@Input({ required: true }) enabled!: boolean;
|
@Input({ required: true, transform: toBoolean }) enabled = false;
|
||||||
@Input() error = false;
|
@Input({ transform: toBoolean }) error = false;
|
||||||
@Input() position: 'top' | 'bottom' = 'bottom';
|
@Input() position: 'top' | 'bottom' = 'bottom';
|
||||||
@Output() action: EventEmitter<() => void>; // Will emit an event when triggered.
|
@Output() action: EventEmitter<() => void>; // Will emit an event when triggered.
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { CorePromisedValue } from '@classes/promised-value';
|
||||||
import { AsyncDirective } from '@classes/async-directive';
|
import { AsyncDirective } from '@classes/async-directive';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
import { CoreWait } from '@singletons/wait';
|
import { CoreWait } from '@singletons/wait';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to show a loading spinner and message while data is being loaded.
|
* Component to show a loading spinner and message while data is being loaded.
|
||||||
|
@ -51,9 +52,9 @@ import { CoreWait } from '@singletons/wait';
|
||||||
})
|
})
|
||||||
export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, AsyncDirective, OnDestroy {
|
export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, AsyncDirective, OnDestroy {
|
||||||
|
|
||||||
@Input() hideUntil: unknown = false; // Determine when should the contents be shown.
|
@Input({ transform: toBoolean }) hideUntil = false; // Determine when should the contents be shown.
|
||||||
@Input() message?: string; // Message to show while loading.
|
@Input() message?: string; // Message to show while loading.
|
||||||
@Input() fullscreen = true; // Use the whole screen.
|
@Input({ transform: toBoolean }) fullscreen = true; // Use the whole screen.
|
||||||
|
|
||||||
uniqueId: string;
|
uniqueId: string;
|
||||||
loaded = false;
|
loaded = false;
|
||||||
|
@ -108,7 +109,7 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
this.changeState(!!this.hideUntil);
|
this.changeState(this.hideUntil);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,7 +117,7 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A
|
||||||
*/
|
*/
|
||||||
ngOnChanges(changes: { [name: string]: SimpleChange }): void {
|
ngOnChanges(changes: { [name: string]: SimpleChange }): void {
|
||||||
if (changes.hideUntil) {
|
if (changes.hideUntil) {
|
||||||
this.changeState(!!this.hideUntil);
|
this.changeState(this.hideUntil);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import { CoreUtils, CoreUtilsOpenFileOptions, OpenFileAction } from '@services/u
|
||||||
import { CoreForms } from '@singletons/form';
|
import { CoreForms } from '@singletons/form';
|
||||||
import { CorePath } from '@singletons/path';
|
import { CorePath } from '@singletons/path';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to handle a local file. Only files inside the app folder can be managed.
|
* Component to handle a local file. Only files inside the app folder can be managed.
|
||||||
|
@ -41,8 +42,8 @@ import { CorePlatform } from '@services/platform';
|
||||||
export class CoreLocalFileComponent implements OnInit {
|
export class CoreLocalFileComponent implements OnInit {
|
||||||
|
|
||||||
@Input() file?: FileEntry; // A fileEntry retrieved using CoreFileProvider.getFile or similar.
|
@Input() file?: FileEntry; // A fileEntry retrieved using CoreFileProvider.getFile or similar.
|
||||||
@Input() manage?: boolean | string; // Whether the user can manage the file (edit and delete).
|
@Input({ transform: toBoolean }) manage = false; // Whether the user can manage the file (edit and delete).
|
||||||
@Input() overrideClick?: boolean | string; // Whether the default item click should be overridden.
|
@Input({ transform: toBoolean }) overrideClick = false; // Whether the default item click should be overridden.
|
||||||
@Output() onDelete = new EventEmitter<void>(); // Will notify when the file is deleted.
|
@Output() onDelete = new EventEmitter<void>(); // Will notify when the file is deleted.
|
||||||
@Output() onRename = new EventEmitter<{ file: FileEntry }>(); // Will notify when the file is renamed.
|
@Output() onRename = new EventEmitter<{ file: FileEntry }>(); // Will notify when the file is renamed.
|
||||||
@Output() onClick = new EventEmitter<void>(); // Will notify when the file is clicked. Only if overrideClick is true.
|
@Output() onClick = new EventEmitter<void>(); // Will notify when the file is clicked. Only if overrideClick is true.
|
||||||
|
@ -67,8 +68,6 @@ export class CoreLocalFileComponent implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.manage = CoreUtils.isTrueOrOne(this.manage);
|
|
||||||
|
|
||||||
if (!this.file) {
|
if (!this.file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +118,7 @@ export class CoreLocalFileComponent implements OnInit {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
if (!isOpenButton && CoreUtils.isTrueOrOne(this.overrideClick) && this.onClick.observed) {
|
if (!isOpenButton && this.overrideClick && this.onClick.observed) {
|
||||||
this.onClick.emit();
|
this.onClick.emit();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Input, OnInit, AfterViewInit, ElementRef } from '@angular/core';
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
import { Component, Input, AfterViewInit, ElementRef } from '@angular/core';
|
||||||
|
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,9 +33,9 @@ import { Translate } from '@singletons';
|
||||||
templateUrl: 'core-mark-required.html',
|
templateUrl: 'core-mark-required.html',
|
||||||
styleUrls: ['mark-required.scss'],
|
styleUrls: ['mark-required.scss'],
|
||||||
})
|
})
|
||||||
export class CoreMarkRequiredComponent implements OnInit, AfterViewInit {
|
export class CoreMarkRequiredComponent implements AfterViewInit {
|
||||||
|
|
||||||
@Input('core-mark-required') coreMarkRequired: boolean | string = true;
|
@Input({ alias: 'core-mark-required', transform: toBoolean }) coreMarkRequired = true;
|
||||||
|
|
||||||
protected hostElement: HTMLElement;
|
protected hostElement: HTMLElement;
|
||||||
requiredLabel = Translate.instant('core.required');
|
requiredLabel = Translate.instant('core.required');
|
||||||
|
@ -46,13 +46,6 @@ export class CoreMarkRequiredComponent implements OnInit, AfterViewInit {
|
||||||
this.hostElement = element.nativeElement;
|
this.hostElement = element.nativeElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.coreMarkRequired = CoreUtils.isTrueOrOne(this.coreMarkRequired);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { CoreSites } from '@services/sites';
|
||||||
import { CoreText } from '@singletons/text';
|
import { CoreText } from '@singletons/text';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreUserWithAvatar } from '@components/user-avatar/user-avatar';
|
import { CoreUserWithAvatar } from '@components/user-avatar/user-avatar';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to handle a message in a conversation.
|
* Component to handle a message in a conversation.
|
||||||
|
@ -39,7 +40,7 @@ export class CoreMessageComponent implements OnInit {
|
||||||
@Input() instanceId = 0;
|
@Input() instanceId = 0;
|
||||||
@Input() courseId?: number;
|
@Input() courseId?: number;
|
||||||
@Input() contextLevel: ContextLevel = ContextLevel.SYSTEM;
|
@Input() contextLevel: ContextLevel = ContextLevel.SYSTEM;
|
||||||
@Input() showDelete = false;
|
@Input({ transform: toBoolean }) showDelete = false;
|
||||||
@Output() onDeleteMessage = new EventEmitter<void>();
|
@Output() onDeleteMessage = new EventEmitter<void>();
|
||||||
@Output() onUndoDeleteMessage = new EventEmitter<void>();
|
@Output() onUndoDeleteMessage = new EventEmitter<void>();
|
||||||
@Output() afterRender = new EventEmitter<void>();
|
@Output() afterRender = new EventEmitter<void>();
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreConstants, ModPurpose } from '@/core/constants';
|
import { CoreConstants, ModPurpose } from '@/core/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
|
@ -54,10 +55,10 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
||||||
@Input() fallbackTranslation = ''; // Fallback translation string if cannot auto translate.
|
@Input() fallbackTranslation = ''; // Fallback translation string if cannot auto translate.
|
||||||
@Input() componentId?: number; // Component Id for external icons.
|
@Input() componentId?: number; // Component Id for external icons.
|
||||||
@Input() modicon?: string; // Module icon url or local url.
|
@Input() modicon?: string; // Module icon url or local url.
|
||||||
@Input() showAlt = true; // Show alt otherwise it's only presentation icon.
|
@Input({ transform: toBoolean }) showAlt = true; // Show alt otherwise it's only presentation icon.
|
||||||
@Input() purpose: ModPurpose = ModPurpose.MOD_PURPOSE_OTHER; // Purpose of the module.
|
@Input() purpose: ModPurpose = ModPurpose.MOD_PURPOSE_OTHER; // Purpose of the module.
|
||||||
@Input() @HostBinding('class.colorize') colorize = true; // Colorize the icon. Only applies on 4.0 onwards.
|
@Input({ transform: toBoolean }) @HostBinding('class.colorize') colorize = true; // Colorize the icon. Only applies on 4.0+.
|
||||||
@Input() isBranded?: boolean; // If icon is branded and no colorize will be applied.
|
@Input({ transform: toBoolean }) isBranded = false; // If icon is branded and no colorize will be applied.
|
||||||
|
|
||||||
@HostBinding('class.branded') brandedClass?: boolean;
|
@HostBinding('class.branded') brandedClass?: boolean;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
|
|
||||||
import { CoreLang, CoreLangFormat } from '@services/lang';
|
import { CoreLang, CoreLangFormat } from '@services/lang';
|
||||||
|
@ -32,7 +33,7 @@ export class CoreRecaptchaComponent implements OnInit {
|
||||||
@Input() publicKey?: string; // The site public key.
|
@Input() publicKey?: string; // The site public key.
|
||||||
@Input() modelValueName = 'recaptcharesponse'; // Name of the model property where to store the response.
|
@Input() modelValueName = 'recaptcharesponse'; // Name of the model property where to store the response.
|
||||||
@Input() siteUrl = ''; // The site URL. If not defined, current site.
|
@Input() siteUrl = ''; // The site URL. If not defined, current site.
|
||||||
@Input() showRequiredError = false; // Whether to display the required error if recaptcha hasn't been answered.
|
@Input({ transform: toBoolean }) showRequiredError = false; // Whether to display the required error if recaptcha not answered.
|
||||||
|
|
||||||
expired = false;
|
expired = false;
|
||||||
|
|
||||||
|
|
|
@ -12,15 +12,15 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Input, Output, EventEmitter, OnInit, ViewChild, ElementRef } from '@angular/core';
|
import { Component, Input, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core';
|
||||||
import { CoreConfig } from '@services/config';
|
import { CoreConfig } from '@services/config';
|
||||||
import { CoreEvents } from '@singletons/events';
|
import { CoreEvents } from '@singletons/events';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { CoreForms } from '@singletons/form';
|
import { CoreForms } from '@singletons/form';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to display a "send message form".
|
* Component to display a "send message form".
|
||||||
|
@ -37,12 +37,12 @@ import { CorePlatform } from '@services/platform';
|
||||||
templateUrl: 'core-send-message-form.html',
|
templateUrl: 'core-send-message-form.html',
|
||||||
styleUrls: ['send-message-form.scss'],
|
styleUrls: ['send-message-form.scss'],
|
||||||
})
|
})
|
||||||
export class CoreSendMessageFormComponent implements OnInit {
|
export class CoreSendMessageFormComponent {
|
||||||
|
|
||||||
@Input() message = ''; // Input text.
|
@Input() message = ''; // Input text.
|
||||||
@Input() placeholder = ''; // Placeholder for the input area.
|
@Input() placeholder = ''; // Placeholder for the input area.
|
||||||
@Input() showKeyboard = false; // If keyboard is shown or not.
|
@Input({ transform: toBoolean }) showKeyboard = false; // If keyboard is shown or not.
|
||||||
@Input() sendDisabled = false; // If send is disabled.
|
@Input({ transform: toBoolean }) sendDisabled = false; // If send is disabled.
|
||||||
@Output() onSubmit: EventEmitter<string>; // Send data when submitting the message form.
|
@Output() onSubmit: EventEmitter<string>; // Send data when submitting the message form.
|
||||||
@Output() onResize: EventEmitter<void>; // Emit when resizing the textarea.
|
@Output() onResize: EventEmitter<void>; // Emit when resizing the textarea.
|
||||||
|
|
||||||
|
@ -68,10 +68,6 @@ export class CoreSendMessageFormComponent implements OnInit {
|
||||||
}, CoreSites.getCurrentSiteId());
|
}, CoreSites.getCurrentSiteId());
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.showKeyboard = CoreUtils.isTrueOrOne(this.showKeyboard);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Form submitted.
|
* Form submitted.
|
||||||
*
|
*
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { Component, ContentChild, Input, Output, TemplateRef, EventEmitter } fro
|
||||||
import { CoreSiteBasicInfo } from '@services/sites';
|
import { CoreSiteBasicInfo } from '@services/sites';
|
||||||
import { CoreAccountsList } from '@features/login/services/login-helper';
|
import { CoreAccountsList } from '@features/login/services/login-helper';
|
||||||
import { CoreSitesFactory } from '@services/sites-factory';
|
import { CoreSitesFactory } from '@services/sites-factory';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to display a list of sites (accounts).
|
* Component to display a list of sites (accounts).
|
||||||
|
@ -43,8 +44,8 @@ import { CoreSitesFactory } from '@services/sites-factory';
|
||||||
export class CoreSitesListComponent<T extends CoreSiteBasicInfo> {
|
export class CoreSitesListComponent<T extends CoreSiteBasicInfo> {
|
||||||
|
|
||||||
@Input({ required: true }) accountsList!: CoreAccountsList<T>;
|
@Input({ required: true }) accountsList!: CoreAccountsList<T>;
|
||||||
@Input() sitesClickable = false; // Whether the sites are clickable.
|
@Input({ transform: toBoolean }) sitesClickable = false; // Whether the sites are clickable.
|
||||||
@Input() currentSiteClickable?: boolean; // If set, specify a different clickable value for current site.
|
@Input({ transform: toBoolean }) currentSiteClickable = false; // If set, specify a different clickable value for current site.
|
||||||
@Output() onSiteClicked = new EventEmitter<T>();
|
@Output() onSiteClicked = new EventEmitter<T>();
|
||||||
|
|
||||||
@ContentChild('siteItem') siteItemTemplate?: TemplateRef<{site: T; isCurrentSite: boolean}>;
|
@ContentChild('siteItem') siteItemTemplate?: TemplateRef<{site: T; isCurrentSite: boolean}>;
|
||||||
|
|
|
@ -22,6 +22,7 @@ import {
|
||||||
|
|
||||||
import { CoreTabsBaseComponent } from '@classes/tabs';
|
import { CoreTabsBaseComponent } from '@classes/tabs';
|
||||||
import { CoreTabComponent } from './tab';
|
import { CoreTabComponent } from './tab';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component displays some top scrollable tabs that will autohide on vertical scroll.
|
* This component displays some top scrollable tabs that will autohide on vertical scroll.
|
||||||
|
@ -44,7 +45,7 @@ import { CoreTabComponent } from './tab';
|
||||||
})
|
})
|
||||||
export class CoreTabsComponent extends CoreTabsBaseComponent<CoreTabComponent> implements AfterViewInit {
|
export class CoreTabsComponent extends CoreTabsBaseComponent<CoreTabComponent> implements AfterViewInit {
|
||||||
|
|
||||||
@Input() parentScrollable = false; // Determine if the scroll should be in the parent content or the tab itself.
|
@Input({ transform: toBoolean }) parentScrollable = false; // Determine if scroll should be in the parent content or the tab.
|
||||||
@Input() layout: 'icon-top' | 'icon-start' | 'icon-end' | 'icon-bottom' | 'icon-hide' | 'label-hide' = 'icon-hide';
|
@Input() layout: 'icon-top' | 'icon-start' | 'icon-end' | 'icon-bottom' | 'icon-hide' | 'label-hide' = 'icon-hide';
|
||||||
|
|
||||||
@ViewChild('originalTabs')
|
@ViewChild('originalTabs')
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, ElementRef } from '@angular/core';
|
import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, ElementRef } from '@angular/core';
|
||||||
import { CoreUser } from '@features/user/services/user';
|
import { CoreUser } from '@features/user/services/user';
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ export class CoreTimerComponent implements OnInit, OnDestroy {
|
||||||
@Input() timeLeftClass?: string; // Name of the class to apply with each second. By default, 'core-timer-timeleft-'.
|
@Input() timeLeftClass?: string; // Name of the class to apply with each second. By default, 'core-timer-timeleft-'.
|
||||||
@Input() timeLeftClassThreshold = 100; // Number of seconds to start adding the timeLeftClass. Set it to -1 to not add it.
|
@Input() timeLeftClassThreshold = 100; // Number of seconds to start adding the timeLeftClass. Set it to -1 to not add it.
|
||||||
@Input() align = 'start'; // Where to align the time and text. Defaults to 'start'. Other values: 'center', 'end'.
|
@Input() align = 'start'; // Where to align the time and text. Defaults to 'start'. Other values: 'center', 'end'.
|
||||||
@Input() hidable = false; // Whether the user can hide the time left.
|
@Input({ transform: toBoolean }) hidable = false; // Whether the user can hide the time left.
|
||||||
@Input() timeUpText?: string; // Text to show when the timer reaches 0. If not defined, 'core.timesup'.
|
@Input() timeUpText?: string; // Text to show when the timer reaches 0. If not defined, 'core.timesup'.
|
||||||
@Input() mode: CoreTimerMode = CoreTimerMode.ITEM; // How to display data.
|
@Input() mode: CoreTimerMode = CoreTimerMode.ITEM; // How to display data.
|
||||||
@Input() underTimeClassThresholds = []; // Number of seconds to add the class 'core-timer-under-'.
|
@Input() underTimeClassThresholds = []; // Number of seconds to add the class 'core-timer-under-'.
|
||||||
|
@ -45,7 +46,7 @@ export class CoreTimerComponent implements OnInit, OnDestroy {
|
||||||
/**
|
/**
|
||||||
* @deprecated since 4.4. Use hidable instead.
|
* @deprecated since 4.4. Use hidable instead.
|
||||||
*/
|
*/
|
||||||
@Input() hiddable?: boolean; // Whether the user can hide the time left.
|
@Input({ transform: toBoolean }) hiddable = false; // Whether the user can hide the time left.
|
||||||
|
|
||||||
timeLeft?: number; // Seconds left to end.
|
timeLeft?: number; // Seconds left to end.
|
||||||
modeBasic = CoreTimerMode.BASIC;
|
modeBasic = CoreTimerMode.BASIC;
|
||||||
|
@ -63,9 +64,9 @@ export class CoreTimerComponent implements OnInit, OnDestroy {
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
// eslint-disable-next-line deprecation/deprecation
|
// eslint-disable-next-line deprecation/deprecation
|
||||||
if (this.hiddable !== undefined && this.hidable === undefined) {
|
if (this.hiddable && !this.hidable) {
|
||||||
// eslint-disable-next-line deprecation/deprecation
|
|
||||||
this.hidable = this.hiddable;
|
this.hidable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeLeftClass = this.timeLeftClass || 'core-timer-timeleft-';
|
const timeLeftClass = this.timeLeftClass || 'core-timer-timeleft-';
|
||||||
|
|
|
@ -23,6 +23,7 @@ import { CoreNetwork } from '@services/network';
|
||||||
import { CoreUserHelper } from '@features/user/services/user-helper';
|
import { CoreUserHelper } from '@features/user/services/user-helper';
|
||||||
import { CoreUrl } from '@singletons/url';
|
import { CoreUrl } from '@singletons/url';
|
||||||
import { CoreSiteInfo } from '@classes/sites/unauthenticated-site';
|
import { CoreSiteInfo } from '@classes/sites/unauthenticated-site';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to display a "user avatar".
|
* Component to display a "user avatar".
|
||||||
|
@ -40,11 +41,11 @@ export class CoreUserAvatarComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
@Input() site?: CoreSiteBasicInfo | CoreSiteInfo; // Site info contains user info.
|
@Input() site?: CoreSiteBasicInfo | CoreSiteInfo; // Site info contains user info.
|
||||||
// The following params will override the ones in user object.
|
// The following params will override the ones in user object.
|
||||||
@Input() profileUrl?: string;
|
@Input() profileUrl?: string;
|
||||||
@Input() linkProfile = true; // Avoid linking to the profile if wanted.
|
@Input({ transform: toBoolean }) linkProfile = true; // Avoid linking to the profile if wanted.
|
||||||
@Input() fullname?: string;
|
@Input() fullname?: string;
|
||||||
@Input() userId?: number; // If provided or found it will be used to link the image to the profile.
|
@Input() userId?: number; // If provided or found it will be used to link the image to the profile.
|
||||||
@Input() courseId?: number;
|
@Input() courseId?: number;
|
||||||
@Input() checkOnline = false; // If want to check and show online status.
|
@Input({ transform: toBoolean }) checkOnline = false; // If want to check and show online status.
|
||||||
@Input() siteId?: string;
|
@Input() siteId?: string;
|
||||||
|
|
||||||
avatarUrl?: string;
|
avatarUrl?: string;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
import { Directive, ElementRef, OnInit, Output, EventEmitter, OnChanges, SimpleChanges, Input } from '@angular/core';
|
import { Directive, ElementRef, OnInit, Output, EventEmitter, OnChanges, SimpleChanges, Input } from '@angular/core';
|
||||||
import { CoreDom } from '@singletons/dom';
|
import { CoreDom } from '@singletons/dom';
|
||||||
|
import { toBoolean } from '../transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directive to emulate click and key actions following aria role button.
|
* Directive to emulate click and key actions following aria role button.
|
||||||
|
@ -25,7 +26,7 @@ export class CoreAriaButtonClickDirective implements OnInit, OnChanges {
|
||||||
|
|
||||||
protected element: HTMLElement;
|
protected element: HTMLElement;
|
||||||
|
|
||||||
@Input() disabled = false;
|
@Input({ transform: toBoolean }) disabled = false;
|
||||||
@Output() ariaButtonClick = new EventEmitter();
|
@Output() ariaButtonClick = new EventEmitter();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|
|
@ -15,9 +15,9 @@
|
||||||
import { Directive, Input, ElementRef, AfterViewInit } from '@angular/core';
|
import { Directive, Input, ElementRef, AfterViewInit } from '@angular/core';
|
||||||
|
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
|
||||||
import { CoreDom } from '@singletons/dom';
|
import { CoreDom } from '@singletons/dom';
|
||||||
import { CoreWait } from '@singletons/wait';
|
import { CoreWait } from '@singletons/wait';
|
||||||
|
import { toBoolean } from '../transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directive to auto focus an element when a view is loaded.
|
* Directive to auto focus an element when a view is loaded.
|
||||||
|
@ -32,7 +32,7 @@ import { CoreWait } from '@singletons/wait';
|
||||||
})
|
})
|
||||||
export class CoreAutoFocusDirective implements AfterViewInit {
|
export class CoreAutoFocusDirective implements AfterViewInit {
|
||||||
|
|
||||||
@Input('core-auto-focus') autoFocus: boolean | string = true;
|
@Input({ alias: 'core-auto-focus', transform: toBoolean }) autoFocus = true;
|
||||||
|
|
||||||
protected element: HTMLIonInputElement | HTMLIonTextareaElement | HTMLIonSearchbarElement | HTMLElement;
|
protected element: HTMLIonInputElement | HTMLIonTextareaElement | HTMLIonSearchbarElement | HTMLElement;
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ export class CoreAutoFocusDirective implements AfterViewInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngAfterViewInit(): Promise<void> {
|
async ngAfterViewInit(): Promise<void> {
|
||||||
if (CoreUtils.isFalseOrZero(this.autoFocus)) {
|
if (!this.autoFocus) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { CoreLoadingComponent } from '@components/loading/loading';
|
||||||
import { CoreCancellablePromise } from '@classes/cancellable-promise';
|
import { CoreCancellablePromise } from '@classes/cancellable-promise';
|
||||||
import { CoreDom } from '@singletons/dom';
|
import { CoreDom } from '@singletons/dom';
|
||||||
import { CoreWait } from '@singletons/wait';
|
import { CoreWait } from '@singletons/wait';
|
||||||
|
import { toBoolean } from '../transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directive to make an element fixed at the bottom collapsible when scrolling.
|
* Directive to make an element fixed at the bottom collapsible when scrolling.
|
||||||
|
@ -37,7 +38,7 @@ import { CoreWait } from '@singletons/wait';
|
||||||
})
|
})
|
||||||
export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy {
|
export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@Input() appearOnBottom = false;
|
@Input({ transform: toBoolean }) appearOnBottom = false; // Whether footer should re-appear when reaching the bottom.
|
||||||
|
|
||||||
protected id = '0';
|
protected id = '0';
|
||||||
protected element: HTMLElement;
|
protected element: HTMLElement;
|
||||||
|
@ -67,9 +68,6 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy {
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.id = String(CoreUtils.getUniqueId('CoreCollapsibleFooterDirective'));
|
this.id = String(CoreUtils.getUniqueId('CoreCollapsibleFooterDirective'));
|
||||||
|
|
||||||
// Only if not present or explicitly falsy it will be false.
|
|
||||||
this.appearOnBottom = !CoreUtils.isFalseOrZero(this.appearOnBottom);
|
|
||||||
this.slotPromise = CoreDom.slotOnContent(this.element);
|
this.slotPromise = CoreDom.slotOnContent(this.element);
|
||||||
|
|
||||||
await this.slotPromise;
|
await this.slotPromise;
|
||||||
|
|
|
@ -20,7 +20,6 @@ import { CoreTabsOutletComponent } from '@components/tabs-outlet/tabs-outlet';
|
||||||
import { CoreTabsComponent } from '@components/tabs/tabs';
|
import { CoreTabsComponent } from '@components/tabs/tabs';
|
||||||
import { CoreSettingsHelper } from '@features/settings/services/settings-helper';
|
import { CoreSettingsHelper } from '@features/settings/services/settings-helper';
|
||||||
import { ScrollDetail } from '@ionic/core';
|
import { ScrollDetail } from '@ionic/core';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
|
||||||
import { CoreDirectivesRegistry } from '@singletons/directives-registry';
|
import { CoreDirectivesRegistry } from '@singletons/directives-registry';
|
||||||
import { CoreDom } from '@singletons/dom';
|
import { CoreDom } from '@singletons/dom';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
|
@ -28,6 +27,7 @@ import { CoreMath } from '@singletons/math';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { CoreFormatTextDirective } from './format-text';
|
import { CoreFormatTextDirective } from './format-text';
|
||||||
import { CoreWait } from '@singletons/wait';
|
import { CoreWait } from '@singletons/wait';
|
||||||
|
import { toBoolean } from '../transforms/boolean';
|
||||||
|
|
||||||
declare module '@singletons/events' {
|
declare module '@singletons/events' {
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ export const COLLAPSIBLE_HEADER_UPDATED = 'collapsible_header_updated';
|
||||||
})
|
})
|
||||||
export class CoreCollapsibleHeaderDirective implements OnInit, OnChanges, OnDestroy {
|
export class CoreCollapsibleHeaderDirective implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
@Input() collapsible = true;
|
@Input({ transform: toBoolean }) collapsible = true;
|
||||||
|
|
||||||
protected page?: HTMLElement;
|
protected page?: HTMLElement;
|
||||||
protected collapsedHeader: HTMLIonHeaderElement;
|
protected collapsedHeader: HTMLIonHeaderElement;
|
||||||
|
@ -106,8 +106,6 @@ export class CoreCollapsibleHeaderDirective implements OnInit, OnChanges, OnDest
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.collapsible = !CoreUtils.isFalseOrZero(this.collapsible);
|
|
||||||
|
|
||||||
if (CoreDom.closest(this.collapsedHeader, 'core-tabs-outlet')) {
|
if (CoreDom.closest(this.collapsedHeader, 'core-tabs-outlet')) {
|
||||||
this.collapsible = false;
|
this.collapsible = false;
|
||||||
}
|
}
|
||||||
|
@ -142,7 +140,6 @@ export class CoreCollapsibleHeaderDirective implements OnInit, OnChanges, OnDest
|
||||||
*/
|
*/
|
||||||
async ngOnChanges(changes: {[name: string]: SimpleChange}): Promise<void> {
|
async ngOnChanges(changes: {[name: string]: SimpleChange}): Promise<void> {
|
||||||
if (changes.collapsible && !changes.collapsible.firstChange) {
|
if (changes.collapsible && !changes.collapsible.firstChange) {
|
||||||
this.collapsible = !CoreUtils.isFalseOrZero(changes.collapsible.currentValue);
|
|
||||||
this.enabled = this.collapsible;
|
this.enabled = this.collapsible;
|
||||||
|
|
||||||
await this.init();
|
await this.init();
|
||||||
|
|
|
@ -56,6 +56,7 @@ import { CoreUrl } from '@singletons/url';
|
||||||
import { CoreIcons } from '@singletons/icons';
|
import { CoreIcons } from '@singletons/icons';
|
||||||
import { ContextLevel } from '../constants';
|
import { ContextLevel } from '../constants';
|
||||||
import { CoreWait } from '@singletons/wait';
|
import { CoreWait } from '@singletons/wait';
|
||||||
|
import { toBoolean } from '../transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directive to format text rendered. It renders the HTML and treats all links and media, using CoreLinkDirective
|
* Directive to format text rendered. It renders the HTML and treats all links and media, using CoreLinkDirective
|
||||||
|
@ -77,19 +78,20 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncDirec
|
||||||
@Input() siteId?: string; // Site ID to use.
|
@Input() siteId?: string; // Site ID to use.
|
||||||
@Input() component?: string; // Component for CoreExternalContentDirective.
|
@Input() component?: string; // Component for CoreExternalContentDirective.
|
||||||
@Input() componentId?: string | number; // Component ID to use in conjunction with the component.
|
@Input() componentId?: string | number; // Component ID to use in conjunction with the component.
|
||||||
@Input() adaptImg?: boolean | string = true; // Whether to adapt images to screen width.
|
@Input({ transform: toBoolean }) adaptImg = true; // Whether to adapt images to screen width.
|
||||||
@Input() clean?: boolean | string; // Whether all the HTML tags should be removed.
|
@Input({ transform: toBoolean }) clean = false; // Whether all the HTML tags should be removed.
|
||||||
@Input() singleLine?: boolean | string; // Whether new lines should be removed (all text in single line). Only if clean=true.
|
@Input({ transform: toBoolean }) singleLine = false; // Whether new lines should be removed. Only if clean=true.
|
||||||
@Input() highlight?: string; // Text to highlight.
|
@Input() highlight?: string; // Text to highlight.
|
||||||
@Input() filter?: boolean | string; // Whether to filter the text. If not defined, true if contextLevel and instanceId are set.
|
@Input({ transform: toBoolean }) filter?: boolean; // Whether to filter the text.
|
||||||
|
// If not defined, true if contextLevel and instanceId are set.
|
||||||
@Input() contextLevel?: ContextLevel; // The context level of the text.
|
@Input() contextLevel?: ContextLevel; // The context level of the text.
|
||||||
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
||||||
@Input() courseId?: number; // Course ID the text belongs to. It can be used to improve performance with filters.
|
@Input() courseId?: number; // Course ID the text belongs to. It can be used to improve performance with filters.
|
||||||
@Input() wsNotFiltered?: boolean | string; // If true it means the WS didn't filter the text for some reason.
|
@Input({ transform: toBoolean }) wsNotFiltered = false; // If true it means the WS didn't filter the text for some reason.
|
||||||
@Input() captureLinks?: boolean; // Whether links should tried to be opened inside the app. Defaults to true.
|
@Input({ transform: toBoolean }) captureLinks = true; // Whether links should tried to be opened inside the app.
|
||||||
@Input() openLinksInApp?: boolean; // Whether links should be opened in InAppBrowser.
|
@Input({ transform: toBoolean }) openLinksInApp = false; // Whether links should be opened in InAppBrowser.
|
||||||
@Input() hideIfEmpty = false; // If true, the tag will contain nothing if text is empty.
|
@Input({ transform: toBoolean }) hideIfEmpty = false; // If true, the tag will contain nothing if text is empty.
|
||||||
@Input() disabled?: boolean; // If disabled, autoplay elements will be disabled.
|
@Input({ transform: toBoolean }) disabled = false; // If disabled, autoplay elements will be disabled.
|
||||||
|
|
||||||
@Output() afterRender: EventEmitter<void>; // Called when the data is rendered.
|
@Output() afterRender: EventEmitter<void>; // Called when the data is rendered.
|
||||||
@Output() onClick: EventEmitter<void> = new EventEmitter(); // Called when clicked.
|
@Output() onClick: EventEmitter<void> = new EventEmitter(); // Called when clicked.
|
||||||
|
@ -361,7 +363,7 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncDirec
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.element.getAttribute('singleLine')) {
|
if (!this.element.getAttribute('singleLine')) {
|
||||||
this.element.setAttribute('singleLine', String(CoreUtils.isTrueOrOne(this.singleLine)));
|
this.element.setAttribute('singleLine', String(this.singleLine));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.text = this.text ? this.text.trim() : '';
|
this.text = this.text ? this.text.trim() : '';
|
||||||
|
@ -423,15 +425,14 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncDirec
|
||||||
this.contextInstanceId = this.courseId;
|
this.contextInstanceId = this.courseId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const filter = this.filter === undefined ?
|
const filter = this.filter ?? !!(this.contextLevel && this.contextInstanceId !== undefined);
|
||||||
!!(this.contextLevel && this.contextInstanceId !== undefined) : CoreUtils.isTrueOrOne(this.filter);
|
|
||||||
|
|
||||||
const options: CoreFilterFormatTextOptions = {
|
const options: CoreFilterFormatTextOptions = {
|
||||||
clean: CoreUtils.isTrueOrOne(this.clean),
|
clean: this.clean,
|
||||||
singleLine: CoreUtils.isTrueOrOne(this.singleLine),
|
singleLine: this.singleLine,
|
||||||
highlight: this.highlight,
|
highlight: this.highlight,
|
||||||
courseId: this.courseId,
|
courseId: this.courseId,
|
||||||
wsNotFiltered: CoreUtils.isTrueOrOne(this.wsNotFiltered),
|
wsNotFiltered: this.wsNotFiltered,
|
||||||
};
|
};
|
||||||
|
|
||||||
let formatted: string;
|
let formatted: string;
|
||||||
|
@ -521,7 +522,7 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncDirec
|
||||||
externalImages.push(externalImage);
|
externalImages.push(externalImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CoreUtils.isTrueOrOne(this.adaptImg) && !img.classList.contains('icon')) {
|
if (this.adaptImg && !img.classList.contains('icon')) {
|
||||||
this.adaptImage(img);
|
this.adaptImage(img);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -27,6 +27,7 @@ import { CoreCustomURLSchemes } from '@services/urlschemes';
|
||||||
import { DomSanitizer } from '@singletons';
|
import { DomSanitizer } from '@singletons';
|
||||||
import { CoreFilepool } from '@services/filepool';
|
import { CoreFilepool } from '@services/filepool';
|
||||||
import { CoreDom } from '@singletons/dom';
|
import { CoreDom } from '@singletons/dom';
|
||||||
|
import { toBoolean } from '../transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directive to open a link in external browser or in the app.
|
* Directive to open a link in external browser or in the app.
|
||||||
|
@ -37,10 +38,10 @@ import { CoreDom } from '@singletons/dom';
|
||||||
export class CoreLinkDirective implements OnInit {
|
export class CoreLinkDirective implements OnInit {
|
||||||
|
|
||||||
@Input() href?: string | SafeUrl; // Link URL.
|
@Input() href?: string | SafeUrl; // Link URL.
|
||||||
@Input() capture?: boolean | string; // If the link needs to be captured by the app.
|
@Input({ transform: toBoolean }) capture = false; // If the link needs to be captured by the app.
|
||||||
@Input() inApp?: boolean | string; // True to open in embedded browser, false to open in system browser.
|
@Input({ transform: toBoolean }) inApp = false; // True to open in embedded browser, false to open in system browser.
|
||||||
@Input() autoLogin: boolean | string = true; // Whether to try to use auto-login. Values yes/no/check are deprecated.
|
@Input({ transform: toBoolean }) autoLogin = true; // Whether to try to use auto-login.
|
||||||
@Input() showBrowserWarning = true; // Whether to show a warning before opening browser. Defaults to true.
|
@Input({ transform: toBoolean }) showBrowserWarning = true; // Whether to show a warning before opening browser.
|
||||||
|
|
||||||
protected element: HTMLElement | HTMLIonFabButtonElement | HTMLIonButtonElement | HTMLIonItemElement;
|
protected element: HTMLElement | HTMLIonFabButtonElement | HTMLIonButtonElement | HTMLIonItemElement;
|
||||||
|
|
||||||
|
@ -93,7 +94,7 @@ export class CoreLinkDirective implements OnInit {
|
||||||
|
|
||||||
const openIn = this.element.getAttribute('data-open-in');
|
const openIn = this.element.getAttribute('data-open-in');
|
||||||
|
|
||||||
if (CoreUtils.isTrueOrOne(this.capture)) {
|
if (this.capture) {
|
||||||
const treated = await CoreContentLinksHelper.handleLink(CoreTextUtils.decodeURI(href), undefined, true, true);
|
const treated = await CoreContentLinksHelper.handleLink(CoreTextUtils.decodeURI(href), undefined, true, true);
|
||||||
|
|
||||||
if (!treated) {
|
if (!treated) {
|
||||||
|
@ -177,8 +178,7 @@ export class CoreLinkDirective implements OnInit {
|
||||||
*/
|
*/
|
||||||
protected async openExternalLink(href: string, openIn?: string | null): Promise<void> {
|
protected async openExternalLink(href: string, openIn?: string | null): Promise<void> {
|
||||||
// Priority order is: core-link inApp attribute > forceOpenLinksIn setting > data-open-in HTML attribute.
|
// Priority order is: core-link inApp attribute > forceOpenLinksIn setting > data-open-in HTML attribute.
|
||||||
const openInApp = this.inApp !== undefined ?
|
const openInApp = this.inApp ??
|
||||||
CoreUtils.isTrueOrOne(this.inApp) :
|
|
||||||
(CoreConstants.CONFIG.forceOpenLinksIn !== 'browser' &&
|
(CoreConstants.CONFIG.forceOpenLinksIn !== 'browser' &&
|
||||||
(CoreConstants.CONFIG.forceOpenLinksIn === 'app' || openIn === 'app'));
|
(CoreConstants.CONFIG.forceOpenLinksIn === 'app' || openIn === 'app'));
|
||||||
|
|
||||||
|
@ -219,11 +219,7 @@ export class CoreLinkDirective implements OnInit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const autoLogin = typeof this.autoLogin === 'boolean' ?
|
if (this.autoLogin) {
|
||||||
this.autoLogin :
|
|
||||||
!CoreUtils.isFalseOrZero(this.autoLogin) && this.autoLogin !== 'no'; // Support deprecated values yes/no/check.
|
|
||||||
|
|
||||||
if (autoLogin) {
|
|
||||||
if (openInApp) {
|
if (openInApp) {
|
||||||
await currentSite.openInAppWithAutoLogin(href);
|
await currentSite.openInAppWithAutoLogin(href);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { CoreSites } from '@services/sites';
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { ContextLevel } from '@/core/constants';
|
import { ContextLevel } from '@/core/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that displays the count of comments.
|
* Component that displays the count of comments.
|
||||||
|
@ -41,7 +42,7 @@ export class CoreCommentsCommentsComponent implements OnInit, OnChanges, OnDestr
|
||||||
@Input() title?: string;
|
@Input() title?: string;
|
||||||
@Output() onLoading = new EventEmitter<boolean>(); // Event that indicates whether the component is loading data.
|
@Output() onLoading = new EventEmitter<boolean>(); // Event that indicates whether the component is loading data.
|
||||||
@Input() courseId?: number; // Course ID the comments belong to. It can be used to improve performance with filters.
|
@Input() courseId?: number; // Course ID the comments belong to. It can be used to improve performance with filters.
|
||||||
@Input() showItem = false; // Show button as an item.
|
@Input({ transform: toBoolean }) showItem = false; // Show button as an item.
|
||||||
|
|
||||||
commentsLoaded = false;
|
commentsLoaded = false;
|
||||||
commentsCount = '';
|
commentsCount = '';
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
Input,
|
Input,
|
||||||
|
@ -70,7 +71,7 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy, DoCheck {
|
||||||
@Input() stylesPath?: string; // The styles URL to apply (only if cssCode is not set).
|
@Input() stylesPath?: string; // The styles URL to apply (only if cssCode is not set).
|
||||||
@Input() extraImports: unknown[] = []; // Extra import modules.
|
@Input() extraImports: unknown[] = []; // Extra import modules.
|
||||||
@Input() extraProviders: Type<unknown>[] = []; // Extra providers.
|
@Input() extraProviders: Type<unknown>[] = []; // Extra providers.
|
||||||
@Input() forceCompile = false; // Set it to true to force compile even if the text/javascript hasn't changed.
|
@Input({ transform: toBoolean }) forceCompile = false; // True to force compile even if the text/javascript hasn't changed.
|
||||||
@Output() created = new EventEmitter<unknown>(); // Will emit an event when the component is instantiated.
|
@Output() created = new EventEmitter<unknown>(); // Will emit an event when the component is instantiated.
|
||||||
@Output() compiling = new EventEmitter<boolean>(); // Event that indicates whether the template is being compiled.
|
@Output() compiling = new EventEmitter<boolean>(); // Event that indicates whether the template is being compiled.
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy, DoCheck {
|
||||||
// Only compile if text/javascript has changed or the forceCompile flag has been set to true.
|
// Only compile if text/javascript has changed or the forceCompile flag has been set to true.
|
||||||
if (this.text === undefined ||
|
if (this.text === undefined ||
|
||||||
!(changes.text || changes.javascript || changes.cssCode || changes.stylesPath ||
|
!(changes.text || changes.javascript || changes.cssCode || changes.stylesPath ||
|
||||||
(changes.forceCompile && CoreUtils.isTrueOrOne(this.forceCompile)))) {
|
(changes.forceCompile && this.forceCompile))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ import { CoreBlockComponentsModule } from '@features/block/components/components
|
||||||
import { CoreCourseComponentsModule } from '../components.module';
|
import { CoreCourseComponentsModule } from '../components.module';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { COURSE_ALL_SECTIONS_PREFERRED_PREFIX } from '@features/course/constants';
|
import { COURSE_ALL_SECTIONS_PREFERRED_PREFIX } from '@features/course/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to display course contents using a certain format. If the format isn't found, use default one.
|
* Component to display course contents using a certain format. If the format isn't found, use default one.
|
||||||
|
@ -90,7 +91,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
@Input() initialSectionNumber?: number; // The section to load first (by number).
|
@Input() initialSectionNumber?: number; // The section to load first (by number).
|
||||||
@Input() initialBlockInstanceId?: number; // The instance to focus.
|
@Input() initialBlockInstanceId?: number; // The instance to focus.
|
||||||
@Input() moduleId?: number; // The module ID to scroll to. Must be inside the initial selected section.
|
@Input() moduleId?: number; // The module ID to scroll to. Must be inside the initial selected section.
|
||||||
@Input() isGuest?: boolean; // If user is accessing using an ACCESS_GUEST enrolment method.
|
@Input({ transform: toBoolean }) isGuest = false; // If user is accessing using an ACCESS_GUEST enrolment method.
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
@ViewChildren(CoreDynamicComponent) dynamicComponents?: QueryList<CoreDynamicComponent<any>>;
|
@ViewChildren(CoreDynamicComponent) dynamicComponents?: QueryList<CoreDynamicComponent<any>>;
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { CoreCourseHelper } from '@features/course/services/course-helper';
|
||||||
import { CoreUser } from '@features/user/services/user';
|
import { CoreUser } from '@features/user/services/user';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to handle activity completion. It shows a checkbox with the current status, and allows manually changing
|
* Component to handle activity completion. It shows a checkbox with the current status, and allows manually changing
|
||||||
|
@ -43,8 +44,8 @@ export class CoreCourseModuleCompletionComponent
|
||||||
extends CoreCourseModuleCompletionBaseComponent
|
extends CoreCourseModuleCompletionBaseComponent
|
||||||
implements OnInit, OnChanges, OnDestroy {
|
implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
@Input() showCompletionConditions = false; // Whether to show activity completion conditions.
|
@Input({ transform: toBoolean }) showCompletionConditions = false; // Whether to show activity completion conditions.
|
||||||
@Input() showManualCompletion = false; // Whether to show manual completion.
|
@Input({ transform: toBoolean }) showManualCompletion = false; // Whether to show manual completion.
|
||||||
|
|
||||||
completed = false;
|
completed = false;
|
||||||
accessibleDescription: string | null = null;
|
accessibleDescription: string | null = null;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
import { ContextLevel } from '@/core/constants';
|
import { ContextLevel } from '@/core/constants';
|
||||||
import { CoreSharedModule } from '@/core/shared.module';
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, HostBinding, Input } from '@angular/core';
|
import { Component, HostBinding, Input } from '@angular/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,7 +50,7 @@ export class CoreCourseModuleDescriptionComponent {
|
||||||
@Input() note?: string; // A note to display along with the description.
|
@Input() note?: string; // A note to display along with the description.
|
||||||
@Input() component?: string; // Component for format text directive.
|
@Input() component?: string; // Component for format text directive.
|
||||||
@Input() componentId?: string | number; // Component ID to use in conjunction with the component.
|
@Input() componentId?: string | number; // Component ID to use in conjunction with the component.
|
||||||
@Input() showFull?: string | boolean; // Whether to always display the full description.
|
@Input({ transform: toBoolean }) showFull = false; // Whether to always display the full description.
|
||||||
@Input() contextLevel?: ContextLevel; // The context level.
|
@Input() contextLevel?: ContextLevel; // The context level.
|
||||||
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
||||||
@Input() courseId?: number; // Course ID the text belongs to. It can be used to improve performance with filters.
|
@Input() courseId?: number; // Course ID the text belongs to. It can be used to improve performance with filters.
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
import { CoreCourse } from '@features/course/services/course';
|
import { CoreCourse } from '@features/course/services/course';
|
||||||
import { CoreCourseModuleCompletionData, CoreCourseModuleData } from '@features/course/services/course-helper';
|
import { CoreCourseModuleCompletionData, CoreCourseModuleData } from '@features/course/services/course-helper';
|
||||||
|
@ -42,13 +43,13 @@ export class CoreCourseModuleInfoComponent implements OnInit {
|
||||||
@Input({ required: true }) componentId!: string | number; // Component ID to use in conjunction with the component.
|
@Input({ required: true }) componentId!: string | number; // Component ID to use in conjunction with the component.
|
||||||
|
|
||||||
@Input() description?: string | false; // The description to display. If false, no description will be shown.
|
@Input() description?: string | false; // The description to display. If false, no description will be shown.
|
||||||
@Input() expandDescription = false; // If the description should be expanded by default.
|
@Input({ transform: toBoolean }) expandDescription = false; // If the description should be expanded by default.
|
||||||
|
|
||||||
@Input() showAvailabilityInfo = false; // If show availability info on the box.
|
@Input({ transform: toBoolean }) showAvailabilityInfo = false; // If show availability info on the box.
|
||||||
|
|
||||||
@Input() hasDataToSync = false; // If the activity has any data to be synced.
|
@Input({ transform: toBoolean }) hasDataToSync = false; // If the activity has any data to be synced.
|
||||||
|
|
||||||
@Input() showManualCompletion = true; // Whether to show manual completion, true by default.
|
@Input({ transform: toBoolean }) showManualCompletion = true; // Whether to show manual completion, true by default.
|
||||||
@Output() completionChanged = new EventEmitter<CoreCourseModuleCompletionData>(); // Notify when completion changes.
|
@Output() completionChanged = new EventEmitter<CoreCourseModuleCompletionData>(); // Notify when completion changes.
|
||||||
|
|
||||||
modicon = '';
|
modicon = '';
|
||||||
|
|
|
@ -34,6 +34,7 @@ import { ModalController, NgZone } from '@singletons';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { CoreSharedModule } from '@/core/shared.module';
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to display a module summary modal.
|
* Component to display a module summary modal.
|
||||||
|
@ -54,7 +55,7 @@ export class CoreCourseModuleSummaryComponent implements OnInit, OnDestroy {
|
||||||
@Input() moduleId = 0; // Module ID the component belongs to.
|
@Input() moduleId = 0; // Module ID the component belongs to.
|
||||||
@Input() component = ''; // Component name.
|
@Input() component = ''; // Component name.
|
||||||
@Input() description = ''; // Module description.
|
@Input() description = ''; // Module description.
|
||||||
@Input() hasOffline = false; // If it has offline data to be synced.
|
@Input({ transform: toBoolean }) hasOffline = false; // If it has offline data to be synced.
|
||||||
@Input() displayOptions: CoreCourseModuleSummaryDisplayOptions = {};
|
@Input() displayOptions: CoreCourseModuleSummaryDisplayOptions = {};
|
||||||
|
|
||||||
loaded = false; // If the component has been loaded.
|
loaded = false; // If the component has been loaded.
|
||||||
|
|
|
@ -30,6 +30,7 @@ import {
|
||||||
import { CoreConstants, DownloadStatus } from '@/core/constants';
|
import { CoreConstants, DownloadStatus } from '@/core/constants';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to display a module entry in a list of modules.
|
* Component to display a module entry in a list of modules.
|
||||||
|
@ -47,15 +48,15 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@Input({ required: true }) module!: CoreCourseModuleData; // The module to render.
|
@Input({ required: true }) module!: CoreCourseModuleData; // The module to render.
|
||||||
@Input() section?: CoreCourseSection; // The section the module belongs to.
|
@Input() section?: CoreCourseSection; // The section the module belongs to.
|
||||||
@Input() showActivityDates = false; // Whether to show activity dates.
|
@Input({ transform: toBoolean }) showActivityDates = false; // Whether to show activity dates.
|
||||||
@Input() showCompletionConditions = false; // Whether to show activity completion conditions.
|
@Input({ transform: toBoolean }) showCompletionConditions = false; // Whether to show activity completion conditions.
|
||||||
@Input() showLegacyCompletion?: boolean; // Whether to show module completion in the old format.
|
@Input({ transform: toBoolean }) showLegacyCompletion?: boolean; // Whether to show module completion in the old format.
|
||||||
@Input() showCompletion = true; // Whether to show module completion.
|
@Input({ transform: toBoolean }) showCompletion = true; // Whether to show module completion.
|
||||||
@Input() showAvailability = true; // Whether to show module availability.
|
@Input({ transform: toBoolean }) showAvailability = true; // Whether to show module availability.
|
||||||
@Input() showExtra = true; // Whether to show extra badges.
|
@Input({ transform: toBoolean }) showExtra = true; // Whether to show extra badges.
|
||||||
@Input() showDownloadStatus = true; // Whether to show download status.
|
@Input({ transform: toBoolean }) showDownloadStatus = true; // Whether to show download status.
|
||||||
@Input() showIndentation = true; // Whether to show indentation
|
@Input({ transform: toBoolean }) showIndentation = true; // Whether to show indentation
|
||||||
@Input() isLastViewed = false; // Whether it's the last module viewed in a course.
|
@Input({ transform: toBoolean }) isLastViewed = false; // Whether it's the last module viewed in a course.
|
||||||
@Output() completionChanged = new EventEmitter<CoreCourseModuleCompletionData>(); // Notify when module completion changes.
|
@Output() completionChanged = new EventEmitter<CoreCourseModuleCompletionData>(); // Notify when module completion changes.
|
||||||
@HostBinding('class.indented') indented = false;
|
@HostBinding('class.indented') indented = false;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import { CoreCoursesHelper, CoreEnrolledCourseDataWithExtraInfoAndOptions } from
|
||||||
import { CoreCoursesCourseOptionsMenuComponent } from '../course-options-menu/course-options-menu';
|
import { CoreCoursesCourseOptionsMenuComponent } from '../course-options-menu/course-options-menu';
|
||||||
import { CoreEnrolHelper } from '@features/enrol/services/enrol-helper';
|
import { CoreEnrolHelper } from '@features/enrol/services/enrol-helper';
|
||||||
import { CoreDownloadStatusTranslatable } from '@components/download-refresh/download-refresh';
|
import { CoreDownloadStatusTranslatable } from '@components/download-refresh/download-refresh';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This directive is meant to display an item for a list of courses.
|
* This directive is meant to display an item for a list of courses.
|
||||||
|
@ -44,7 +45,7 @@ import { CoreDownloadStatusTranslatable } from '@components/download-refresh/dow
|
||||||
export class CoreCoursesCourseListItemComponent implements OnInit, OnDestroy, OnChanges {
|
export class CoreCoursesCourseListItemComponent implements OnInit, OnDestroy, OnChanges {
|
||||||
|
|
||||||
@Input({ required: true }) course!: CoreCourseListItem; // The course to render.
|
@Input({ required: true }) course!: CoreCourseListItem; // The course to render.
|
||||||
@Input() showDownload = false; // If true, will show download button.
|
@Input({ transform: toBoolean }) showDownload = false; // If true, will show download button.
|
||||||
@Input() layout: 'listwithenrol'|'summarycard'|'list'|'card' = 'listwithenrol';
|
@Input() layout: 'listwithenrol'|'summarycard'|'list'|'card' = 'listwithenrol';
|
||||||
|
|
||||||
enrolmentIcons: CoreCoursesEnrolmentIcons[] = [];
|
enrolmentIcons: CoreCoursesEnrolmentIcons[] = [];
|
||||||
|
|
|
@ -47,6 +47,7 @@ import { ContextLevel } from '@/core/constants';
|
||||||
import { CoreSwiper } from '@singletons/swiper';
|
import { CoreSwiper } from '@singletons/swiper';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreWait } from '@singletons/wait';
|
import { CoreWait } from '@singletons/wait';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to display a rich text editor if enabled.
|
* Component to display a rich text editor if enabled.
|
||||||
|
@ -73,7 +74,7 @@ export class CoreEditorRichTextEditorComponent implements OnInit, AfterViewInit,
|
||||||
@Input() name = 'core-rich-text-editor'; // Name to set to the textarea.
|
@Input() name = 'core-rich-text-editor'; // Name to set to the textarea.
|
||||||
@Input() component?: string; // The component to link the files to.
|
@Input() component?: string; // The component to link the files to.
|
||||||
@Input() componentId?: number; // An ID to use in conjunction with the component.
|
@Input() componentId?: number; // An ID to use in conjunction with the component.
|
||||||
@Input() autoSave?: boolean | string; // Whether to auto-save the contents in a draft. Defaults to true.
|
@Input({ transform: toBoolean }) autoSave = true; // Whether to auto-save the contents in a draft.
|
||||||
@Input() contextLevel?: ContextLevel; // The context level of the text.
|
@Input() contextLevel?: ContextLevel; // The context level of the text.
|
||||||
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
||||||
@Input() elementId?: string; // An ID to set to the element.
|
@Input() elementId?: string; // An ID to set to the element.
|
||||||
|
@ -887,7 +888,7 @@ export class CoreEditorRichTextEditorComponent implements OnInit, AfterViewInit,
|
||||||
*/
|
*/
|
||||||
protected shouldAutoSaveDrafts(): boolean {
|
protected shouldAutoSaveDrafts(): boolean {
|
||||||
return !!CoreSites.getCurrentSite() &&
|
return !!CoreSites.getCurrentSite() &&
|
||||||
(this.autoSave === undefined || CoreUtils.isTrueOrOne(this.autoSave)) &&
|
this.autoSave &&
|
||||||
this.contextLevel !== undefined &&
|
this.contextLevel !== undefined &&
|
||||||
this.contextInstanceId !== undefined &&
|
this.contextInstanceId !== undefined &&
|
||||||
this.elementId !== undefined;
|
this.elementId !== undefined;
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { CoreError } from '@classes/errors/error';
|
||||||
import { CoreCaptureError } from '@classes/errors/captureerror';
|
import { CoreCaptureError } from '@classes/errors/captureerror';
|
||||||
import { CoreCanceledError } from '@classes/errors/cancelederror';
|
import { CoreCanceledError } from '@classes/errors/cancelederror';
|
||||||
import { CorePath } from '@singletons/path';
|
import { CorePath } from '@singletons/path';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page to capture media in browser.
|
* Page to capture media in browser.
|
||||||
|
@ -41,7 +42,7 @@ export class CoreEmulatorCaptureMediaComponent implements OnInit, OnDestroy {
|
||||||
@Input() mimetype?: string;
|
@Input() mimetype?: string;
|
||||||
@Input() extension?: string;
|
@Input() extension?: string;
|
||||||
@Input() quality?: number; // Only for images.
|
@Input() quality?: number; // Only for images.
|
||||||
@Input() returnDataUrl?: boolean; // Whether it should return a data img. Only for images.
|
@Input({ transform: toBoolean }) returnDataUrl = false; // Whether it should return a data img. Only for images.
|
||||||
|
|
||||||
@ViewChild('streamVideo') streamVideo?: ElementRef;
|
@ViewChild('streamVideo') streamVideo?: ElementRef;
|
||||||
@ViewChild('previewVideo') previewVideo?: ElementRef;
|
@ViewChild('previewVideo') previewVideo?: ElementRef;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreSharedModule } from '@/core/shared.module';
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, Input, OnDestroy, ViewChild } from '@angular/core';
|
import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, Input, OnDestroy, ViewChild } from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -32,7 +33,7 @@ export class CoreFileUploaderAudioHistogramComponent implements AfterViewInit, O
|
||||||
private static readonly BARS_GUTTER = 4;
|
private static readonly BARS_GUTTER = 4;
|
||||||
|
|
||||||
@Input({ required: true }) analyser!: AnalyserNode;
|
@Input({ required: true }) analyser!: AnalyserNode;
|
||||||
@Input() paused?: boolean;
|
@Input({ transform: toBoolean }) paused = false;
|
||||||
@ViewChild('canvas') canvasRef?: ElementRef<HTMLCanvasElement>;
|
@ViewChild('canvas') canvasRef?: ElementRef<HTMLCanvasElement>;
|
||||||
|
|
||||||
private element: HTMLElement;
|
private element: HTMLElement;
|
||||||
|
|
|
@ -30,6 +30,7 @@ import { CoreLogger } from '@singletons/logger';
|
||||||
import { CoreH5PCore, CoreH5PDisplayOptions } from '../../classes/core';
|
import { CoreH5PCore, CoreH5PDisplayOptions } from '../../classes/core';
|
||||||
import { CoreH5PHelper } from '../../classes/helper';
|
import { CoreH5PHelper } from '../../classes/helper';
|
||||||
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
|
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to render an iframe with an H5P package.
|
* Component to render an iframe with an H5P package.
|
||||||
|
@ -45,7 +46,7 @@ export class CoreH5PIframeComponent implements OnChanges, OnDestroy {
|
||||||
@Input() onlinePlayerUrl?: string; // The URL of the online player to display the H5P package.
|
@Input() onlinePlayerUrl?: string; // The URL of the online player to display the H5P package.
|
||||||
@Input() trackComponent?: string; // Component to send xAPI events to.
|
@Input() trackComponent?: string; // Component to send xAPI events to.
|
||||||
@Input() contextId?: number; // Context ID. Required for tracking.
|
@Input() contextId?: number; // Context ID. Required for tracking.
|
||||||
@Input() enableInAppFullscreen?: boolean; // Whether to enable our custom in-app fullscreen feature.
|
@Input({ transform: toBoolean }) enableInAppFullscreen = false; // Whether to enable our custom in-app fullscreen feature.
|
||||||
@Input() saveFreq?: number; // Save frequency (in seconds) if enabled.
|
@Input() saveFreq?: number; // Save frequency (in seconds) if enabled.
|
||||||
@Input() state?: string; // Initial content state.
|
@Input() state?: string; // Initial content state.
|
||||||
@Output() onIframeUrlSet = new EventEmitter<{src: string; online: boolean}>();
|
@Output() onIframeUrlSet = new EventEmitter<{src: string; online: boolean}>();
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes/sites/unauthenticated-site';
|
import { CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes/sites/unauthenticated-site';
|
||||||
import { CoreLoginHelper, CoreLoginMethod } from '@features/login/services/login-helper';
|
import { CoreLoginHelper, CoreLoginMethod } from '@features/login/services/login-helper';
|
||||||
|
@ -27,7 +28,7 @@ import { CoreDomUtils } from '@services/utils/dom';
|
||||||
})
|
})
|
||||||
export class CoreLoginMethodsComponent implements OnInit {
|
export class CoreLoginMethodsComponent implements OnInit {
|
||||||
|
|
||||||
@Input() reconnect = false;
|
@Input({ transform: toBoolean }) reconnect = false;
|
||||||
@Input() siteUrl = '';
|
@Input() siteUrl = '';
|
||||||
@Input() siteConfig?: CoreSitePublicConfigResponse;
|
@Input() siteConfig?: CoreSitePublicConfigResponse;
|
||||||
@Input() redirectData?: CoreRedirectPayload;
|
@Input() redirectData?: CoreRedirectPayload;
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { CoreSites } from '@services/sites';
|
||||||
import { CoreModals } from '@services/modals';
|
import { CoreModals } from '@services/modals';
|
||||||
import { CoreMainMenuUserMenuTourComponent } from '../user-menu-tour/user-menu-tour';
|
import { CoreMainMenuUserMenuTourComponent } from '../user-menu-tour/user-menu-tour';
|
||||||
import { CoreMainMenuPage } from '@features/mainmenu/pages/menu/menu';
|
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.
|
* 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 {
|
export class CoreMainMenuUserButtonComponent implements OnInit {
|
||||||
|
|
||||||
@Input() alwaysShow = false;
|
@Input({ transform: toBoolean }) alwaysShow = false;
|
||||||
siteInfo?: CoreSiteInfo;
|
siteInfo?: CoreSiteInfo;
|
||||||
isMainScreen = false;
|
isMainScreen = false;
|
||||||
userTour: CoreUserTourDirectiveOptions = {
|
userTour: CoreUserTourDirectiveOptions = {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { CoreIonicColorNames } from '@singletons/colors';
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { CoreLogger } from '@singletons/logger';
|
||||||
import { CoreQuestionBehaviourButton, CoreQuestionHelper, CoreQuestionQuestion } from '../services/question-helper';
|
import { CoreQuestionBehaviourButton, CoreQuestionHelper, CoreQuestionQuestion } from '../services/question-helper';
|
||||||
import { ContextLevel } from '@/core/constants';
|
import { ContextLevel } from '@/core/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for components to render a question.
|
* Base class for components to render a question.
|
||||||
|
@ -37,11 +38,11 @@ export class CoreQuestionBaseComponent<T extends AddonModQuizQuestion = AddonMod
|
||||||
@Input() component?: string; // The component the question belongs to.
|
@Input() component?: string; // The component the question belongs to.
|
||||||
@Input() componentId?: number; // ID of the component the question belongs to.
|
@Input() componentId?: number; // ID of the component the question belongs to.
|
||||||
@Input() attemptId?: number; // Attempt ID.
|
@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() contextLevel?: ContextLevel; // The context level.
|
||||||
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
||||||
@Input() courseId?: number; // The course the question belongs to (if any).
|
@Input() courseId?: number; // The course the question belongs to (if any).
|
||||||
@Input() review?: boolean; // Whether the user is in review mode.
|
@Input({ transform: toBoolean }) review = false; // Whether the user is in review mode.
|
||||||
@Input() preferredBehaviour?: string; // Preferred behaviour.
|
@Input() preferredBehaviour?: string; // Preferred behaviour.
|
||||||
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
|
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
|
||||||
@Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
|
@Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { ContextLevel } from '@/core/constants';
|
import { ContextLevel } from '@/core/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input, Output, OnInit, EventEmitter, ChangeDetectorRef, Type, ElementRef } from '@angular/core';
|
import { Component, Input, Output, OnInit, EventEmitter, ChangeDetectorRef, Type, ElementRef } from '@angular/core';
|
||||||
import { AsyncDirective } from '@classes/async-directive';
|
import { AsyncDirective } from '@classes/async-directive';
|
||||||
import { CorePromisedValue } from '@classes/promised-value';
|
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() componentId?: number; // ID of the component the question belongs to.
|
||||||
@Input() attemptId?: number; // Attempt ID.
|
@Input() attemptId?: number; // Attempt ID.
|
||||||
@Input() usageId?: number; // Usage 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() contextLevel?: ContextLevel; // The context level.
|
||||||
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
||||||
@Input() courseId?: number; // Course ID the question belongs to (if any). It can be used to improve performance with filters.
|
@Input() 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.
|
@Input() preferredBehaviour?: string; // Behaviour to use.
|
||||||
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
|
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
|
||||||
@Output() onAbort= new EventEmitter<void>(); // Will emit an event if the question should be aborted.
|
@Output() onAbort= new EventEmitter<void>(); // Will emit an event if the question should be aborted.
|
||||||
|
@ -78,8 +79,6 @@ export class CoreQuestionComponent implements OnInit, AsyncDirective {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.offlineEnabled = CoreUtils.isTrueOrOne(this.offlineEnabled);
|
|
||||||
|
|
||||||
if (!this.question || (this.question.type != 'random' &&
|
if (!this.question || (this.question.type != 'random' &&
|
||||||
!CoreQuestionDelegate.isQuestionSupported(this.question.type))) {
|
!CoreQuestionDelegate.isQuestionSupported(this.question.type))) {
|
||||||
this.promisedReady.resolve();
|
this.promisedReady.resolve();
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
import { CoreReportBuilder } from '@features/reportbuilder/services/reportbuilder';
|
import { CoreReportBuilder } from '@features/reportbuilder/services/reportbuilder';
|
||||||
|
|
||||||
|
@ -22,9 +23,9 @@ import { CoreReportBuilder } from '@features/reportbuilder/services/reportbuilde
|
||||||
})
|
})
|
||||||
export class CoreReportBuilderReportColumnComponent {
|
export class CoreReportBuilderReportColumnComponent {
|
||||||
|
|
||||||
@Input() isExpanded = false;
|
@Input({ transform: toBoolean }) isExpanded = false;
|
||||||
@Input() isExpandable = false;
|
@Input({ transform: toBoolean }) isExpandable = false;
|
||||||
@Input() showFirstTitle = false;
|
@Input({ transform: toBoolean }) showFirstTitle = false;
|
||||||
@Input({ required: true }) columnIndex!: number;
|
@Input({ required: true }) columnIndex!: number;
|
||||||
@Input({ required: true }) rowIndex!: number;
|
@Input({ required: true }) rowIndex!: number;
|
||||||
@Input({ required: true }) column!: string | number;
|
@Input({ required: true }) column!: string | number;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
import { CoreError } from '@classes/errors/error';
|
import { CoreError } from '@classes/errors/error';
|
||||||
import {
|
import {
|
||||||
|
@ -41,7 +42,7 @@ import { map } from 'rxjs/operators';
|
||||||
export class CoreReportBuilderReportDetailComponent implements OnInit {
|
export class CoreReportBuilderReportDetailComponent implements OnInit {
|
||||||
|
|
||||||
@Input({ required: true }) reportId!: string;
|
@Input({ required: true }) reportId!: string;
|
||||||
@Input() isBlock = true;
|
@Input({ transform: toBoolean }) isBlock = true;
|
||||||
@Input() perPage?: number;
|
@Input() perPage?: number;
|
||||||
@Input() layout: 'card' | 'table' | 'adaptative' = 'adaptative';
|
@Input() layout: 'card' | 'table' | 'adaptative' = 'adaptative';
|
||||||
@Output() onReportLoaded = new EventEmitter<CoreReportBuilderReportDetail>();
|
@Output() onReportLoaded = new EventEmitter<CoreReportBuilderReportDetail>();
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { CoreEvents } from '@singletons/events';
|
||||||
import { ModalController } from '@singletons';
|
import { ModalController } from '@singletons';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreSharedModule } from '@/core/shared.module';
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
type Filter<T=unknown> = T & { checked: boolean };
|
type Filter<T=unknown> = T & { checked: boolean };
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ export class CoreSearchGlobalSearchFiltersComponent implements OnInit {
|
||||||
allCourses: boolean | null = true;
|
allCourses: boolean | null = true;
|
||||||
courses: Filter<CoreEnrolledCourseData>[] = [];
|
courses: Filter<CoreEnrolledCourseData>[] = [];
|
||||||
|
|
||||||
@Input() hideCourses?: boolean;
|
@Input({ transform: toBoolean }) hideCourses = false;
|
||||||
@Input() filters?: CoreSearchGlobalSearchFilters;
|
@Input() filters?: CoreSearchGlobalSearchFilters;
|
||||||
|
|
||||||
private newFilters: CoreSearchGlobalSearchFilters = {};
|
private newFilters: CoreSearchGlobalSearchFilters = {};
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input, Output, EventEmitter, OnChanges } from '@angular/core';
|
import { Component, Input, Output, EventEmitter, OnChanges } from '@angular/core';
|
||||||
import { CoreSearchGlobalSearchResult, CoreSearchGlobalSearchResultContext } from '@features/search/services/global-search';
|
import { CoreSearchGlobalSearchResult, CoreSearchGlobalSearchResultContext } from '@features/search/services/global-search';
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ import { CoreSearchGlobalSearchResult, CoreSearchGlobalSearchResultContext } fro
|
||||||
export class CoreSearchGlobalSearchResultComponent implements OnChanges {
|
export class CoreSearchGlobalSearchResultComponent implements OnChanges {
|
||||||
|
|
||||||
@Input({ required: true }) result!: CoreSearchGlobalSearchResult;
|
@Input({ required: true }) result!: CoreSearchGlobalSearchResult;
|
||||||
@Input() showCourse?: boolean;
|
@Input({ transform: toBoolean }) showCourse = true;
|
||||||
|
|
||||||
renderedContext: CoreSearchGlobalSearchResultContext | null = null;
|
renderedContext: CoreSearchGlobalSearchResultContext | null = null;
|
||||||
renderedIcon: string | null = null;
|
renderedIcon: string | null = null;
|
||||||
|
@ -46,7 +47,7 @@ export class CoreSearchGlobalSearchResultComponent implements OnChanges {
|
||||||
private computeRenderedContext(): CoreSearchGlobalSearchResultContext | null {
|
private computeRenderedContext(): CoreSearchGlobalSearchResultContext | null {
|
||||||
const context = { ...this.result.context } ?? {};
|
const context = { ...this.result.context } ?? {};
|
||||||
|
|
||||||
if (this.showCourse === false) {
|
if (!this.showCourse) {
|
||||||
delete context.courseName;
|
delete context.courseName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
|
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
|
||||||
|
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
|
||||||
import { CoreSearchHistory } from '../../services/search-history.service';
|
import { CoreSearchHistory } from '../../services/search-history.service';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreSearchHistoryDBRecord } from '../../services/search-history-db';
|
import { CoreSearchHistoryDBRecord } from '../../services/search-history-db';
|
||||||
import { CoreForms } from '@singletons/form';
|
import { CoreForms } from '@singletons/form';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to display a "search box".
|
* 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() searchLabel?: string; // Label to be used on action button.
|
||||||
@Input() placeholder?: string; // Placeholder text for search text input.
|
@Input() placeholder?: string; // Placeholder text for search text input.
|
||||||
@Input() autocorrect = 'on'; // Enables/disable Autocorrection on 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({ transform: toBoolean }) spellcheck = true; // Enables/disable Spellchecker on search text input.
|
||||||
@Input() autoFocus: string | boolean = false; // Enables/disable Autofocus when entering view.
|
@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() lengthCheck = 3; // Check value length before submit. If 0, any string will be submitted.
|
||||||
@Input() showClear = true; // Show/hide clear button.
|
@Input({ transform: toBoolean }) showClear = true; // Show/hide clear button.
|
||||||
@Input() disabled = false; // Disables the input text.
|
@Input({ transform: toBoolean }) disabled = false; // Disables the input text.
|
||||||
@Input() initialSearch = ''; // Initial search text.
|
@Input() initialSearch = ''; // Initial search text.
|
||||||
|
|
||||||
/* If provided. It will save and display a history of searches for this particular Id.
|
/* 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 {
|
ngOnInit(): void {
|
||||||
this.searchLabel = this.searchLabel || Translate.instant('core.search');
|
this.searchLabel = this.searchLabel || Translate.instant('core.search');
|
||||||
this.placeholder = this.placeholder || 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;
|
this.searchText = this.initialSearch;
|
||||||
|
|
||||||
if (this.searchArea) {
|
if (this.searchArea) {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreSharedModule } from '@/core/shared.module';
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, OnInit, Input } from '@angular/core';
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
import { FileEntry } from '@awesome-cordova-plugins/file/ngx';
|
import { FileEntry } from '@awesome-cordova-plugins/file/ngx';
|
||||||
|
|
||||||
|
@ -36,10 +37,10 @@ export class CoreSharedFilesListModalComponent implements OnInit {
|
||||||
|
|
||||||
@Input() siteId?: string;
|
@Input() siteId?: string;
|
||||||
@Input() mimetypes?: string[];
|
@Input() mimetypes?: string[];
|
||||||
@Input() manage?: boolean;
|
@Input({ transform: toBoolean }) manage = false;
|
||||||
@Input() pick?: boolean; // To pick a file you MUST use a modal.
|
@Input({ transform: toBoolean }) pick = false; // To pick a file you MUST use a modal.
|
||||||
@Input() path?: string;
|
@Input() path?: string;
|
||||||
@Input() hideSitePicker?: boolean;
|
@Input({ transform: toBoolean }) hideSitePicker = false;
|
||||||
|
|
||||||
title?: string;
|
title?: string;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import { CoreNavigator } from '@services/navigator';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
import { CorePath } from '@singletons/path';
|
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.
|
* 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() siteId?: string;
|
||||||
@Input() mimetypes?: string[];
|
@Input() mimetypes?: string[];
|
||||||
@Input() isModal?: boolean; // Whether the component is loaded in a modal.
|
@Input({ transform: toBoolean }) isModal = false; // Whether the component is loaded in a modal.
|
||||||
@Input() manage?: boolean;
|
@Input({ transform: toBoolean }) manage = false;
|
||||||
@Input() pick?: boolean; // To pick a file you MUST use a modal.
|
@Input({ transform: toBoolean }) pick = false; // To pick a file you MUST use a modal.
|
||||||
@Input() path?: string;
|
@Input() path?: string;
|
||||||
@Input() showSitePicker?: boolean;
|
@Input({ transform: toBoolean }) showSitePicker = false;
|
||||||
@Output() onPathChanged = new EventEmitter<string>();
|
@Output() onPathChanged = new EventEmitter<string>();
|
||||||
@Output() onFilePicked = new EventEmitter<FileEntry>();
|
@Output() onFilePicked = new EventEmitter<FileEntry>();
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@ import { Input, OnInit, ElementRef, Directive } from '@angular/core';
|
||||||
|
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
|
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
|
||||||
import { CoreSitePluginsCallWSBaseDirective } from './call-ws-directive';
|
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.
|
* 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 {
|
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() 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(
|
constructor(
|
||||||
element: ElementRef,
|
element: ElementRef,
|
||||||
|
@ -72,7 +72,7 @@ export class CoreSitePluginsCallWSOnClickBaseDirective extends CoreSitePluginsCa
|
||||||
try {
|
try {
|
||||||
await super.callWS();
|
await super.callWS();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (this.showError === undefined || CoreUtils.isTrueOrOne(this.showError)) {
|
if (this.showError) {
|
||||||
CoreDomUtils.showErrorModalDefault(
|
CoreDomUtils.showErrorModalDefault(
|
||||||
error,
|
error,
|
||||||
Translate.instant('core.serverconnection', {
|
Translate.instant('core.serverconnection', {
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { Component, OnInit, Input } from '@angular/core';
|
||||||
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '@addons/mod/assign/services/assign';
|
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '@addons/mod/assign/services/assign';
|
||||||
import { AddonModAssignFeedbackDelegate } from '@addons/mod/assign/services/feedback-delegate';
|
import { AddonModAssignFeedbackDelegate } from '@addons/mod/assign/services/feedback-delegate';
|
||||||
import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/classes/compile-init-component';
|
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.
|
* Component that displays an assign feedback plugin created using a site plugin.
|
||||||
|
@ -33,8 +34,8 @@ export class CoreSitePluginsAssignFeedbackComponent extends CoreSitePluginsCompi
|
||||||
@Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
|
@Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
|
||||||
@Input({ required: true }) userId!: number; // The user ID of the submission.
|
@Input({ required: true }) userId!: number; // The user ID of the submission.
|
||||||
@Input() configs?: Record<string,string>; // The configs for the plugin.
|
@Input() configs?: Record<string,string>; // The configs for the plugin.
|
||||||
@Input() canEdit = false; // Whether the user can edit.
|
@Input({ transform: toBoolean }) canEdit = false; // Whether the user can edit.
|
||||||
@Input() edit = false; // Whether the user is editing.
|
@Input({ transform: toBoolean }) edit = false; // Whether the user is editing.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { Component, OnInit, Input } from '@angular/core';
|
||||||
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '@addons/mod/assign/services/assign';
|
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '@addons/mod/assign/services/assign';
|
||||||
import { AddonModAssignSubmissionDelegate } from '@addons/mod/assign/services/submission-delegate';
|
import { AddonModAssignSubmissionDelegate } from '@addons/mod/assign/services/submission-delegate';
|
||||||
import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/classes/compile-init-component';
|
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.
|
* Component that displays an assign submission plugin created using a site plugin.
|
||||||
|
@ -32,8 +33,8 @@ export class CoreSitePluginsAssignSubmissionComponent extends CoreSitePluginsCom
|
||||||
@Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
|
@Input({ required: true }) submission!: AddonModAssignSubmission; // The submission.
|
||||||
@Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
|
@Input({ required: true }) plugin!: AddonModAssignPlugin; // The plugin object.
|
||||||
@Input() configs?: Record<string, string>; // The configs for the plugin.
|
@Input() configs?: Record<string, string>; // The configs for the plugin.
|
||||||
@Input() edit = false; // Whether the user is editing.
|
@Input({ transform: toBoolean }) edit = false; // Whether the user is editing.
|
||||||
@Input() allowOffline = false; // Whether to allow offline.
|
@Input({ transform: toBoolean }) allowOffline = false; // Whether to allow offline.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { ContextLevel } from '@/core/constants';
|
import { ContextLevel } from '@/core/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||||
|
|
||||||
import { CoreQuestionBehaviourDelegate } from '@features/question/services/behaviour-delegate';
|
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() component?: string; // The component the question belongs to.
|
||||||
@Input() componentId?: number; // ID of the component the question belongs to.
|
@Input() componentId?: number; // ID of the component the question belongs to.
|
||||||
@Input() attemptId?: number; // Attempt ID.
|
@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() contextLevel?: ContextLevel; // The context level.
|
||||||
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
||||||
@Input() courseId?: number; // Course ID the question belongs to (if any). It can be used to improve performance with filters.
|
@Input() 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.
|
@Input() preferredBehaviour?: string; // Preferred behaviour.
|
||||||
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
|
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
|
||||||
@Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
|
@Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
|
||||||
|
@ -58,6 +59,8 @@ export class CoreSitePluginsQuestionBehaviourComponent extends CoreSitePluginsCo
|
||||||
this.jsData.offlineEnabled = this.offlineEnabled;
|
this.jsData.offlineEnabled = this.offlineEnabled;
|
||||||
this.jsData.contextLevel = this.contextLevel;
|
this.jsData.contextLevel = this.contextLevel;
|
||||||
this.jsData.contextInstanceId = this.contextInstanceId;
|
this.jsData.contextInstanceId = this.contextInstanceId;
|
||||||
|
this.jsData.courseId = this.courseId;
|
||||||
|
this.jsData.review = this.review;
|
||||||
this.jsData.buttonClicked = this.buttonClicked;
|
this.jsData.buttonClicked = this.buttonClicked;
|
||||||
this.jsData.onAbort = this.onAbort;
|
this.jsData.onAbort = this.onAbort;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { ContextLevel } from '@/core/constants';
|
import { ContextLevel } from '@/core/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||||
|
|
||||||
import { AddonModQuizQuestion } from '@features/question/classes/base-question-component';
|
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() component?: string; // The component the question belongs to.
|
||||||
@Input() componentId?: number; // ID of the component the question belongs to.
|
@Input() componentId?: number; // ID of the component the question belongs to.
|
||||||
@Input() attemptId?: number; // Attempt ID.
|
@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() contextLevel?: ContextLevel; // The context level.
|
||||||
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
@Input() contextInstanceId?: number; // The instance ID related to the context.
|
||||||
@Input() courseId?: number; // Course ID the question belongs to (if any). It can be used to improve performance with filters.
|
@Input() 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.
|
@Input() preferredBehaviour?: string; // Preferred behaviour.
|
||||||
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
|
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
|
||||||
@Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
|
@Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { FormGroup } from '@angular/forms';
|
||||||
import { AddonModQuizAccessRuleDelegate } from '@addons/mod/quiz/services/access-rules-delegate';
|
import { AddonModQuizAccessRuleDelegate } from '@addons/mod/quiz/services/access-rules-delegate';
|
||||||
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
|
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '@addons/mod/quiz/services/quiz';
|
||||||
import { CoreSitePluginsCompileInitComponent } from '@features/siteplugins/classes/compile-init-component';
|
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.
|
* 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() rule?: string; // The name of the rule.
|
||||||
@Input() quiz?: AddonModQuizQuizWSData; // The quiz the rule belongs to.
|
@Input() quiz?: AddonModQuizQuizWSData; // The quiz the rule belongs to.
|
||||||
@Input() attempt?: AddonModQuizAttemptWSData; // The attempt being started/continued.
|
@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() siteId?: string; // Site ID.
|
||||||
@Input() form?: FormGroup; // Form where to add the form control.
|
@Input() form?: FormGroup; // Form where to add the form control.
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { ContextLevel } from '@/core/constants';
|
import { ContextLevel } from '@/core/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, OnInit, Input } from '@angular/core';
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
import { FormGroup } from '@angular/forms';
|
import { FormGroup } from '@angular/forms';
|
||||||
|
|
||||||
|
@ -32,9 +33,9 @@ import { CoreUserProfileFieldDelegate } from '@features/user/services/user-profi
|
||||||
export class CoreSitePluginsUserProfileFieldComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
|
export class CoreSitePluginsUserProfileFieldComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
|
||||||
|
|
||||||
@Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
|
@Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
|
||||||
@Input() signup = false; // True if editing the field in signup. Defaults to false.
|
@Input({ transform: toBoolean }) signup = false; // True if editing the field in signup.
|
||||||
@Input() edit = false; // True if editing the field. Defaults to false.
|
@Input({ transform: toBoolean }) edit = false; // True if editing the field.
|
||||||
@Input() disabled = false; // True if disabled. Defaults to false.
|
@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() 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() registerAuth?: string; // Register auth method. E.g. 'email'.
|
||||||
@Input() contextLevel?: ContextLevel; // The context level.
|
@Input() contextLevel?: ContextLevel; // The context level.
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { AddonWorkshopAssessmentStrategyDelegate } from '@addons/mod/workshop/services/assessment-strategy-delegate';
|
import { AddonWorkshopAssessmentStrategyDelegate } from '@addons/mod/workshop/services/assessment-strategy-delegate';
|
||||||
import { AddonModWorkshopGetAssessmentFormFieldsParsedData } from '@addons/mod/workshop/services/workshop';
|
import { AddonModWorkshopGetAssessmentFormFieldsParsedData } from '@addons/mod/workshop/services/workshop';
|
||||||
import { AddonModWorkshopSubmissionAssessmentWithFormData } from '@addons/mod/workshop/services/workshop-helper';
|
import { AddonModWorkshopSubmissionAssessmentWithFormData } from '@addons/mod/workshop/services/workshop-helper';
|
||||||
|
@ -30,7 +31,7 @@ export class CoreSitePluginsWorkshopAssessmentStrategyComponent extends CoreSite
|
||||||
|
|
||||||
@Input({ required: true }) workshopId!: number;
|
@Input({ required: true }) workshopId!: number;
|
||||||
@Input({ required: true }) assessment!: AddonModWorkshopSubmissionAssessmentWithFormData;
|
@Input({ required: true }) assessment!: AddonModWorkshopSubmissionAssessmentWithFormData;
|
||||||
@Input({ required: true }) edit!: boolean;
|
@Input({ required: true, transform: toBoolean }) edit = false;
|
||||||
@Input({ required: true }) selectedValues!: AddonModWorkshopGetAssessmentFormFieldsParsedData[];
|
@Input({ required: true }) selectedValues!: AddonModWorkshopGetAssessmentFormFieldsParsedData[];
|
||||||
@Input({ required: true }) fieldErrors!: Record<string, string>;
|
@Input({ required: true }) fieldErrors!: Record<string, string>;
|
||||||
@Input({ required: true }) strategy!: string;
|
@Input({ required: true }) strategy!: string;
|
||||||
|
|
|
@ -15,12 +15,12 @@
|
||||||
import { Directive, Input, ElementRef, Optional } from '@angular/core';
|
import { Directive, Input, ElementRef, Optional } from '@angular/core';
|
||||||
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
|
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
|
||||||
import { Md5 } from 'ts-md5';
|
import { Md5 } from 'ts-md5';
|
||||||
|
|
||||||
import { CoreSitePluginsCallWSOnClickBaseDirective } from '../classes/call-ws-click-directive';
|
import { CoreSitePluginsCallWSOnClickBaseDirective } from '../classes/call-ws-click-directive';
|
||||||
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
|
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
|
||||||
import { CoreSitePlugins } from '../services/siteplugins';
|
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
|
* 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() method?: string; // The method to get the new content. If not provided, use the same method as current page.
|
||||||
@Input() args?: Record<string, unknown>; // The params to get the new content.
|
@Input() args?: Record<string, unknown>; // The params to get the new content.
|
||||||
@Input() title?: string; // The title to display with the new content. Only if samePage=false.
|
@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() 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.
|
@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.
|
// 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.
|
// If true is supplied instead of an object, all initial variables from current page will be copied.
|
||||||
@Input() jsData?: Record<string, unknown> | boolean;
|
@Input() jsData?: Record<string, unknown> | boolean;
|
||||||
@Input() newContentPreSets?: CoreSiteWSPreSets; // The preSets for the WS call of the new content.
|
@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(
|
constructor(
|
||||||
element: ElementRef,
|
element: ElementRef,
|
||||||
|
@ -93,7 +93,7 @@ export class CoreSitePluginsCallWSNewContentDirective extends CoreSitePluginsCal
|
||||||
jsData = this.parentContent?.data || {};
|
jsData = this.parentContent?.data || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CoreUtils.isTrueOrOne(this.samePage)) {
|
if (this.samePage) {
|
||||||
// Update the parent content (if it exists).
|
// Update the parent content (if it exists).
|
||||||
this.parentContent?.updateContent(args, this.component, this.method, jsData, this.newContentPreSets);
|
this.parentContent?.updateContent(args, this.component, this.method, jsData, this.newContentPreSets);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -16,10 +16,10 @@ import { Directive, Input, ElementRef, Optional } from '@angular/core';
|
||||||
|
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreToasts } from '@services/toasts';
|
import { CoreToasts } from '@services/toasts';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
import { CoreSitePluginsCallWSOnClickBaseDirective } from '../classes/call-ws-click-directive';
|
import { CoreSitePluginsCallWSOnClickBaseDirective } from '../classes/call-ws-click-directive';
|
||||||
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
|
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:
|
* 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 {
|
export class CoreSitePluginsCallWSDirective extends CoreSitePluginsCallWSOnClickBaseDirective {
|
||||||
|
|
||||||
@Input() successMessage?: string; // Message to show on success. If not supplied, no message. If empty, default message.
|
@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({ transform: toBoolean }) goBackOnSuccess = false; // 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 }) refreshOnSuccess = false; // Whether to refresh the current view if the WS call is successful.
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
element: ElementRef,
|
element: ElementRef,
|
||||||
|
@ -66,9 +66,9 @@ export class CoreSitePluginsCallWSDirective extends CoreSitePluginsCallWSOnClick
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
protected async wsCallSuccess(): Promise<void> {
|
protected async wsCallSuccess(): Promise<void> {
|
||||||
if (CoreUtils.isTrueOrOne(this.goBackOnSuccess)) {
|
if (this.goBackOnSuccess) {
|
||||||
await CoreNavigator.back();
|
await CoreNavigator.back();
|
||||||
} else if (CoreUtils.isTrueOrOne(this.refreshOnSuccess) && this.parentContent) {
|
} else if (this.refreshOnSuccess && this.parentContent) {
|
||||||
this.parentContent.refreshContent(true);
|
this.parentContent.refreshContent(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,10 @@ import { Md5 } from 'ts-md5';
|
||||||
|
|
||||||
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
|
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
|
||||||
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
|
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
|
||||||
import { CoreSitePlugins } from '../services/siteplugins';
|
import { CoreSitePlugins } from '../services/siteplugins';
|
||||||
import { CoreForms } from '@singletons/form';
|
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
|
* 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() method?: string; // The method to get the new content. If not provided, use the same method as current page.
|
||||||
@Input() args?: Record<string, unknown>; // The params to get the new content.
|
@Input() args?: Record<string, unknown>; // The params to get the new content.
|
||||||
@Input() title?: string; // The title to display with the new content. Only if samePage=false.
|
@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() 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.
|
@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.
|
// 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.
|
// If true is supplied instead of an object, all initial variables from current page will be copied.
|
||||||
@Input() jsData?: Record<string, unknown> | boolean;
|
@Input() jsData?: Record<string, unknown> | boolean;
|
||||||
@Input() preSets?: CoreSiteWSPreSets; // The preSets for the WS call of the new content.
|
@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;
|
protected element: HTMLElement;
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ export class CoreSitePluginsNewContentDirective implements OnInit {
|
||||||
jsData = this.parentContent?.data || {};
|
jsData = this.parentContent?.data || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CoreUtils.isTrueOrOne(this.samePage)) {
|
if (this.samePage) {
|
||||||
// Update the parent content (if it exists).
|
// Update the parent content (if it exists).
|
||||||
this.parentContent?.updateContent(args, this.component, this.method, jsData, this.preSets);
|
this.parentContent?.updateContent(args, this.component, this.method, jsData, this.preSets);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { ContextLevel } from '@/core/constants';
|
import { ContextLevel } from '@/core/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { FormGroup, Validators, FormControl } from '@angular/forms';
|
import { FormGroup, Validators, FormControl } from '@angular/forms';
|
||||||
|
|
||||||
|
@ -28,9 +29,9 @@ import { CoreUserProfileField } from '@features/user/services/user';
|
||||||
export abstract class CoreUserProfileFieldBaseComponent<T = string> implements OnInit {
|
export abstract class CoreUserProfileFieldBaseComponent<T = string> implements OnInit {
|
||||||
|
|
||||||
@Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
|
@Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
|
||||||
@Input() signup = false; // True if editing the field in signup. Defaults to false.
|
@Input({ transform: toBoolean }) signup = false; // True if editing the field in signup.
|
||||||
@Input() edit = false; // True if editing the field. Defaults to false.
|
@Input({ transform: toBoolean }) edit = false; // True if editing the field.
|
||||||
@Input() disabled = false; // True if disabled. Defaults to false.
|
@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() 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() registerAuth?: string; // Register auth method. E.g. 'email'.
|
||||||
@Input() contextLevel?: ContextLevel; // The context level.
|
@Input() contextLevel?: ContextLevel; // The context level.
|
||||||
|
|
|
@ -20,6 +20,7 @@ import { CoreUserProfileField } from '@features/user/services/user';
|
||||||
import { CoreUserProfileFieldDelegate } from '@features/user/services/user-profile-field-delegate';
|
import { CoreUserProfileFieldDelegate } from '@features/user/services/user-profile-field-delegate';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { ContextLevel } from '@/core/constants';
|
import { ContextLevel } from '@/core/constants';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directive to render user profile field.
|
* Directive to render user profile field.
|
||||||
|
@ -31,8 +32,8 @@ import { ContextLevel } from '@/core/constants';
|
||||||
export class CoreUserProfileFieldComponent implements OnInit {
|
export class CoreUserProfileFieldComponent implements OnInit {
|
||||||
|
|
||||||
@Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
|
@Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
|
||||||
@Input() signup = false; // True if editing the field in signup. Defaults to false.
|
@Input({ transform: toBoolean }) signup = false; // True if editing the field in signup.
|
||||||
@Input() edit = false; // True if editing the field. Defaults to false.
|
@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() 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() registerAuth?: string; // Register auth method. E.g. 'email'.
|
||||||
@Input() contextLevel?: ContextLevel; // The context level.
|
@Input() contextLevel?: ContextLevel; // The context level.
|
||||||
|
@ -57,13 +58,13 @@ export class CoreUserProfileFieldComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.data.field = this.field;
|
this.data.field = this.field;
|
||||||
this.data.edit = CoreUtils.isTrueOrOne(this.edit);
|
this.data.edit = this.edit;
|
||||||
this.data.contextLevel = this.contextLevel;
|
this.data.contextLevel = this.contextLevel;
|
||||||
this.data.contextInstanceId = this.contextInstanceId;
|
this.data.contextInstanceId = this.contextInstanceId;
|
||||||
this.data.courseId = this.courseId;
|
this.data.courseId = this.courseId;
|
||||||
|
|
||||||
if (this.edit) {
|
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.disabled = 'locked' in this.field && CoreUtils.isTrueOrOne(this.field.locked);
|
||||||
this.data.form = this.form;
|
this.data.form = this.form;
|
||||||
this.data.registerAuth = this.registerAuth;
|
this.data.registerAuth = this.registerAuth;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
import { ContextLevel } from '@/core/constants';
|
import { ContextLevel } from '@/core/constants';
|
||||||
import { CoreSharedModule } from '@/core/shared.module';
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { CoreFileEntry } from '@services/file-helper';
|
import { CoreFileEntry } from '@services/file-helper';
|
||||||
|
|
||||||
|
@ -39,11 +40,11 @@ export class CoreViewerTextComponent {
|
||||||
@Input() component?: string; // Component to use in format-text.
|
@Input() component?: string; // Component to use in format-text.
|
||||||
@Input() componentId?: string | number; // Component ID to use in format-text.
|
@Input() componentId?: string | number; // Component ID to use in format-text.
|
||||||
@Input() files?: CoreFileEntry[]; // List of files.
|
@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() contextLevel?: ContextLevel; // The context level.
|
||||||
@Input() instanceId?: number; // The instance ID related to the context.
|
@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() 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.
|
* Close modal.
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue