Merge pull request #2764 from crazyserver/MOBILE-3752

Mobile 3752
main
Dani Palou 2021-05-14 08:30:40 +02:00 committed by GitHub
commit 7a2c27fe57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
177 changed files with 364 additions and 436 deletions

View File

@ -310,7 +310,7 @@ function array_contains {
print_title 'Generating language from code...'
gulp lang
npx gulp lang
print_title 'Getting languages'

View File

@ -10,8 +10,9 @@ DEFAULT_LASTVERSION='4.0'
# Checks if AWS is available and configured.
function check_aws {
aws --version &> /dev/null
AWS_SERVICE=1
aws --version &> /dev/null
if [ $? -ne 0 ]; then
AWS_SERVICE=0
echo 'AWS not installed. Check https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html for more info.'
@ -19,7 +20,7 @@ function check_aws {
fi
# In order to login to AWS, use credentials file or AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY vars.
if [ ! -f ~/.aws/credentials ] && [ [ -z $AWS_ACCESS_KEY_ID ] || [ -z $AWS_SECRET_ACCESS_KEY ] ]; then
if [ ! -f ~/.aws/credentials ] && ([ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]); then
AWS_SERVICE=0
lastversion=$DEFAULT_LASTVERSION
echo 'AWS Cannot authenticate. Use aws configure or set the proper env vars.'
@ -63,6 +64,13 @@ function get_last_version {
lastversion=$DEFAULT_LASTVERSION
}
# Create langfolder
function create_langfolder {
if [ ! -d $LANGPACKSFOLDER ]; then
mkdir $LANGPACKSFOLDER
fi
}
# Get all language list from AWS.
function get_all_languages_aws {
langsfiles=`aws s3 ls s3://$BUCKET/$lastversion/`
@ -87,6 +95,8 @@ function get_language {
get_last_version
create_langfolder
echo "Getting $lang language"
pushd $LANGPACKSFOLDER > /dev/null
@ -115,7 +125,7 @@ function get_languages {
return
fi
else
mkdir $LANGPACKSFOLDER
create_langfolder
fi

View File

@ -12,11 +12,11 @@
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
</ion-refresher>
<core-loading [hideUntil]="badges.loaded">
<core-empty-box *ngIf="badges.empty" icon="fas-trophy"
<core-empty-box *ngIf="badges.empty" icon="fas-trophy"
[message]="'addon.badges.nobadges' | translate">
</core-empty-box>
<ion-list *ngIf="!badges.empty" class="ion-no-margin">
<ion-list *ngIf="!badges.empty" class="ion-no-margin">
<ion-item button class="ion-text-wrap" *ngFor="let badge of badges.items" [attr.aria-label]="badge.name"
(click)="badges.select(badge)" [attr.aria-current]="badges.getItemAriaCurrent(badge)">
<ion-avatar slot="start">

View File

@ -34,8 +34,6 @@ export class AddonBlockLearningPlansHandlerService extends CoreBlockBaseHandler
* @return Data or promise resolved with the data.
*/
getDisplayData(): CoreBlockHandlerData {
// @todo
return {
title: 'addon.block_learningplans.pluginname',
class: 'addon-block-learning-plans',

View File

@ -327,8 +327,8 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
/**
* Helper function to help with filter values.
*
* @param showCondition If true, filter will be shown.
* @param disabledCondition If true, and showCondition is also met, it will be shown as disabled.
* @param showCondition If true, filter will be shown.
* @param disabledCondition If true, and showCondition is also met, it will be shown as disabled.
* @return show / disabled / hidden value.
*/
protected getShowFilterValue(showCondition: boolean, disabledCondition: boolean): string {
@ -507,7 +507,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
courses.forEach((course) => {
if (course.hidden) {
this.courses.hidden.push(course);
} else {
} else {
this.courses.all.push(course);
if ((course.enddate && course.enddate < today) || course.completed) {

View File

@ -21,7 +21,7 @@ import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler
import { makeSingleton } from '@singletons';
/**
* Block handler.
* Block handler.
*/
@Injectable({ providedIn: 'root' })
export class AddonBlockMyOverviewHandlerService extends CoreBlockBaseHandler {

View File

@ -3,8 +3,8 @@
.addon-calendar-navigation {
padding-top: 5px;
padding-left: 10px;
padding-right: 10px;
padding-left: 10px;
padding-right: 10px;
}
.addon-calendar-months {

View File

@ -2,7 +2,7 @@
<core-empty-box *ngIf="!filteredEvents || !filteredEvents.length" icon="fas-calendar" [message]="'addon.calendar.noevents' | translate">
</core-empty-box>
<ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin">
<ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin">
<ng-container *ngFor="let event of filteredEvents">
<ion-item class="ion-text-wrap addon-calendar-event" [attr.aria-label]="event.name" (click)="eventClicked(event)" button
[ngClass]="['addon-calendar-eventtype-'+event.eventtype]">

View File

@ -12,7 +12,7 @@
<core-context-menu-item *ngIf="!isCurrentDay" [priority]="900" [content]="'addon.calendar.today' | translate"
iconAction="fas-calendar-day" (action)="goToCurrentDay()">
</core-context-menu-item>
<core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline" [priority]="400"
<core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline" [priority]="400"
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event)"
[iconAction]="syncIcon" [closeOnClick]="false">
</core-context-menu-item>
@ -57,7 +57,7 @@
[message]="'addon.calendar.noevents' | translate">
</core-empty-box>
<ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin">
<ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin">
<ng-container *ngFor="let event of filteredEvents">
<ion-item class="addon-calendar-event ion-text-wrap" [attr.aria-label]="event.name" (click)="gotoEvent(event.id)"
[class.item-dimmed]="event.ispast" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]" button>

View File

@ -531,7 +531,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
try {
await AddonCalendarHelper.refreshAfterChangeEvent(result.event, numberOfRepetitions);
} catch {
} catch {
// Ignore errors.
}
}

View File

@ -145,7 +145,7 @@
</ion-label>
</ion-item>
<ng-container *ngFor="let reminder of reminders">
<ion-item *ngIf="reminder.time > 0 || defaultTime > 0" class="ion-text-wrap"
<ion-item *ngIf="reminder.time > 0 || defaultTime > 0" class="ion-text-wrap"
[class.item-dimmed]="(reminder.time == -1 ? (event.timestart - defaultTime) : reminder.time) <= currentTime!">
<ion-label>
<p *ngIf="reminder.time == -1">

View File

@ -343,8 +343,8 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
const minute = Math.floor(currentTime / 60) * 60;
// Check if the notification time is in the same minute as we are, so the notification is triggered.
if (notificationTime >= minute && notificationTime < minute + 60) {
notificationTime = currentTime + 1;
if (notificationTime >= minute && notificationTime < minute + 60) {
notificationTime = currentTime + 1;
}
await AddonCalendar.addEventReminder(this.event, notificationTime);

View File

@ -18,7 +18,7 @@
<core-context-menu-item [hidden]="!notificationsEnabled" [priority]="600"
[content]="'core.settings.settings' | translate" (action)="openSettings()" iconAction="fas-cogs">
</core-context-menu-item>
<core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline" [priority]="400"
<core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline" [priority]="400"
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)"
[iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu>

View File

@ -12,7 +12,7 @@
<core-context-menu-item [hidden]="!notificationsEnabled" [priority]="600"
[content]="'core.settings.settings' | translate" (action)="openSettings()" iconAction="fas-cogs">
</core-context-menu-item>
<core-context-menu-item [hidden]="!eventsLoaded || !hasOffline || !isOnline" [priority]="400"
<core-context-menu-item [hidden]="!eventsLoaded || !hasOffline || !isOnline" [priority]="400"
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)"
[iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu>
@ -37,7 +37,7 @@
[message]="'addon.calendar.noevents' | translate">
</core-empty-box>
<ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin">
<ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin">
<ng-container *ngFor="let event of filteredEvents">
<ion-item-divider *ngIf="event.showDate">
<ion-label><h2>{{ event.timestart * 1000 | coreFormatDate: "strftimedayshort" }}</h2></ion-label>

View File

@ -476,7 +476,7 @@ export class AddonCalendarHelperProvider {
const categoryId = filter.categoryId ? Number(filter.categoryId) : undefined;
return events.filter((event) => filter[event.formattedType] &&
return events.filter((event) => filter[event.formattedType] &&
this.shouldDisplayEvent(event, categories, courseId, categoryId));
}

View File

@ -203,7 +203,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
id: event.id,
repeatid: event.repeatid,
timestart: event.timestart,
repeated: data?.repeat ? (event as AddonCalendarEvent).eventcount || 1 : 1,
repeated: data?.repeat ? (event as AddonCalendarEvent).eventcount || 1 : 1,
});
return;

View File

@ -577,7 +577,7 @@ export class AddonCalendarProvider {
value = site.getStoredConfig('calendar_lookahead');
}
return parseInt(value as string, 10);
return parseInt(value as string, 10);
}
/**
@ -1595,7 +1595,7 @@ export class AddonCalendarProvider {
* @param siteId ID of the site the event belongs to. If not defined, use current site.
* @return Promise resolved when stored.
*/
async storeEventInLocalDb(event: AddonCalendarGetEventsEvent | AddonCalendarCalendarEvent, siteId?: string): Promise<void> {
async storeEventInLocalDb(event: AddonCalendarGetEventsEvent | AddonCalendarCalendarEvent, siteId?: string): Promise<void> {
const site = await CoreSites.getSite(siteId);
siteId = site.getId();
try {
@ -1775,7 +1775,7 @@ export const AddonCalendar = makeSingleton(AddonCalendarProvider);
/**
* Data returned by calendar's events_exporter.
* Data returned by core_calendar_get_action_events_by_course and core_calendar_get_action_events_by_timesort WS.
* Data returned by core_calendar_get_action_events_by_course and core_calendar_get_action_events_by_timesort WS.
*/
export type AddonCalendarEvents = {
events: AddonCalendarEvent[]; // Events.
@ -1912,7 +1912,7 @@ export type AddonCalendarEventBase = {
};
/**
* Data returned by calendar's event_exporter. Don't confuse it with AddonCalendarCalendarEvent.
* Data returned by calendar's event_exporter. Don't confuse it with AddonCalendarCalendarEvent.
*/
export type AddonCalendarEvent = AddonCalendarEventBase & {
url: string; // Url.

View File

@ -98,7 +98,7 @@
<ion-badge slot="end" color="success" *ngIf="userCompetency.proficiency">
{{ 'core.yes' | translate }}
</ion-badge>
<ion-badge slot="end" color="danger" *ngIf="!userCompetency.proficiency">
<ion-badge slot="end" color="danger" *ngIf="!userCompetency.proficiency">
{{ 'core.no' | translate }}
</ion-badge>
</ion-item>
@ -112,8 +112,8 @@
</ion-card>
<div *ngIf="competency">
<h3 class="ion-margin-horizontal">{{ 'addon.competency.evidence' | translate }}</h3>
<p class="ion-margin-horizontal" *ngIf="competency.evidence.length == 0">
<h3 class="ion-margin-horizontal">{{ 'addon.competency.evidence' | translate }}</h3>
<p class="ion-margin-horizontal" *ngIf="competency.evidence.length == 0">
{{ 'addon.competency.noevidence' | translate }}
</p>
<ion-card *ngFor="let evidence of competency.evidence">
@ -128,7 +128,7 @@
<ion-item class="ion-text-wrap">
<ion-label>
<p><ion-badge color="dark">{{ evidence.gradename }}</ion-badge></p>
<p class="ion-margin-top" *ngIf="evidence.description">{{ evidence.description }}</p>
<p class="ion-margin-top" *ngIf="evidence.description">{{ evidence.description }}</p>
<blockquote *ngIf="evidence.note">{{ evidence.note }}</blockquote>
</ion-label>
</ion-item>

View File

@ -40,7 +40,7 @@
</ion-item>
</ion-card>
<h3 class="ion-margin-horizontal" *ngIf="competencies && competencies.statistics.competencycount > 0">
<h3 class="ion-margin-horizontal" *ngIf="competencies && competencies.statistics.competencycount > 0">
{{ 'addon.competency.coursecompetencies' | translate }}
</h3>
<ion-card *ngIf="user">

View File

@ -65,7 +65,7 @@
</ion-card>
<ion-card *ngIf="plan">
<ion-card-header class="ion-text-wrap">
<h2>{{ 'addon.competency.learningplancompetencies' | translate }}</h2>
<ion-card-title>{{ 'addon.competency.learningplancompetencies' | translate }}</ion-card-title>
</ion-card-header>
<ion-list>
<ion-item class="ion-text-wrap" *ngIf="plan.competencycount == 0">

View File

@ -15,7 +15,7 @@
<core-empty-box *ngIf="plans.empty" icon="fas-route" [message]="'addon.competency.noplanswerecreated' | translate">
</core-empty-box>
<ion-list *ngIf="!plans.empty" class="ion-no-margin">
<ion-list *ngIf="!plans.empty" class="ion-no-margin">
<ion-item class="ion-text-wrap" *ngFor="let plan of plans.items" [attr.aria-label]="plan.name"
(click)="plans.select(plan)" [attr.aria-current]="plans.getItemAriaCurrent(plan)" button>
<ion-label>

View File

@ -53,7 +53,7 @@
:host-context([dir=rtl]) {
.addon-messages-conversation-item,
.addon-message-discussion {
h2 ion-icon {
h2 ion-icon {
margin-right: 2px;
margin-left: 0;
}

View File

@ -28,7 +28,7 @@
<core-empty-box *ngIf="!hasContacts && searchString != ''" icon="fas-address-book"
[message]="'addon.messages.nousersfound' | translate"></core-empty-box>
<ion-list *ngFor="let contactType of contactTypes" class="ion-no-margin">
<ion-list *ngFor="let contactType of contactTypes" class="ion-no-margin">
<ng-container *ngIf="contacts[contactType] && (contacts[contactType].length > 0 || contactType === searchType)">
<ion-item-divider>
<ion-label><h2>{{ 'addon.messages.type_' + contactType | translate }}</h2></ion-label>
@ -39,7 +39,7 @@
<ion-item class="ion-text-wrap addon-messages-conversation-item"
*ngIf="contact.profileimageurl || contact.profileimageurlsmall"
[attr.aria-label]="contact.fullname" (click)="gotoDiscussion(contact.id)" detail="true" button
[attr.aria-current]="contact.id == discussionUserId ? 'page' : 'false'">
[attr.aria-current]="contact.id == discussionUserId ? 'page' : 'false'">
<core-user-avatar [user]="contact" slot="start" [checkOnline]="contact.showonlinestatus"></core-user-avatar>
<ion-label><h2>{{ contact.fullname }}</h2></ion-label>
</ion-item>

View File

@ -25,10 +25,10 @@
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
</ion-refresher>
<core-loading [hideUntil]="confirmedLoaded" class="core-loading-center">
<ion-list class="ion-no-margin">
<ion-list class="ion-no-margin">
<ion-item class="ion-text-wrap addon-messages-conversation-item" (click)="selectUser(contact.id)" button
*ngFor="let contact of confirmedContacts" [attr.aria-label]="contact.fullname" detail="true"
[attr.aria-current]="contact.id == selectedUserId ? 'page' : 'false'">
[attr.aria-current]="contact.id == selectedUserId ? 'page' : 'false'">
<core-user-avatar slot="start" [user]="contact"
[checkOnline]="contact.showonlinestatus" [linkProfile]="false">
</core-user-avatar>
@ -62,10 +62,10 @@
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
</ion-refresher>
<core-loading [hideUntil]="requestsLoaded" class="core-loading-center">
<ion-list class="ion-no-margin">
<ion-list class="ion-no-margin">
<ion-item class="ion-text-wrap addon-messages-conversation-item" *ngFor="let request of requests"
[attr.aria-label]="request.fullname" (click)="selectUser(request.id)" button
[attr.aria-current]="request.id == selectedUserId ? 'page' : 'false'" detail="true">
[attr.aria-current]="request.id == selectedUserId ? 'page' : 'false'" detail="true">
<core-user-avatar slot="start" [user]="request" [linkProfile]="false"></core-user-avatar>
<ion-label>
<core-format-text [text]="request.fullname" contextLevel="system" [contextInstanceId]="0">

View File

@ -411,7 +411,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
// Fetch messages. Invalidate the cache before fetching.
if (this.groupMessagingEnabled) {
await AddonMessages.invalidateConversationMessages(this.conversationId!);
messages = await this.getConversationMessages(this.pagesLoaded);
messages = await this.getConversationMessages(this.pagesLoaded);
} else {
await AddonMessages.invalidateDiscussionCache(this.userId!);
messages = await this.getDiscussionMessages(this.pagesLoaded);

View File

@ -40,7 +40,7 @@
</ion-item-divider>
<ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let result of search.results" button
[attr.aria-label]="result.fullname" (click)="gotoDiscussion(result.userid, result.messageid)"
[attr.aria-current]="result.userid == discussionUserId ? 'page' : 'false'">
[attr.aria-current]="result.userid == discussionUserId ? 'page' : 'false'">
<core-user-avatar [user]="result" slot="start" [checkOnline]="result.showonlinestatus"></core-user-avatar>
<ion-label>
<h2>{{ result.fullname }}</h2>
@ -52,7 +52,7 @@
<ng-container *ngIf="!search.showResults">
<ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let discussion of discussions" button
[attr.aria-label]="discussion.fullname" (click)="gotoDiscussion(discussion.message!.user)"
[attr.aria-current]="discussion.message!.user == discussionUserId ? 'page' : 'false'">
[attr.aria-current]="discussion.message!.user == discussionUserId ? 'page' : 'false'">
<core-user-avatar [user]="discussion" slot="start" checkOnline="false"></core-user-avatar>
<ion-label>
<h2>{{ discussion.fullname }}</h2>

View File

@ -67,7 +67,7 @@ export class AddonMessagesDiscussions35Page implements OnInit, OnDestroy {
protected route: ActivatedRoute,
) {
this.search.loading = Translate.instant('core.searching');
this.search.loading = Translate.instant('core.searching');
this.loadingMessages = Translate.instant('core.loading');
this.siteId = CoreSites.getCurrentSiteId();

View File

@ -14,7 +14,7 @@
<ion-content>
<core-split-view>
<core-search-box (onSubmit)="search($event)" (onClear)="clearSearch()" [disabled]="disableSearch" autocorrect="off"
[spellcheck]="false" [autoFocus]="true" [lengthCheck]="1" searchArea="AddonMessagesSearch"></core-search-box>
[spellcheck]="false" [autoFocus]="true" [lengthCheck]="1" searchArea="AddonMessagesSearch"></core-search-box>
<core-loading [hideUntil]="!displaySearching" [message]="'core.searching' | translate">
<ion-list *ngIf="displayResults">
@ -43,7 +43,7 @@
<!-- List of results -->
<ion-item class="addon-message-discussion ion-text-wrap" *ngFor="let result of item.results" [attr.aria-label]="result.fullname"
(click)="openConversation(result)" [attr.aria-current]="result == selectedResult ? 'page' : 'false'" detail="true"
(click)="openConversation(result)" [attr.aria-current]="result == selectedResult ? 'page' : 'false'" detail="true"
button>
<core-user-avatar slot="start" [user]="result" [checkOnline]="true" [linkProfile]="false"></core-user-avatar>
<ion-label>

View File

@ -83,7 +83,7 @@
<ng-container *ngIf="!groupMessagingEnabled">
<!-- Tablet view -->
<ion-row class="ion-text-wrap ion-hide-md-down ion-align-items-center">
<ion-col class="ion-margin-horizontal">{{ processor.displayname }}</ion-col>
<ion-col class="ion-margin-horizontal">{{ processor.displayname }}</ion-col>
<ion-col size="2" class="ion-text-center" *ngFor="let state of ['loggedin', 'loggedoff']">
<!-- If notifications not disabled, show toggle. -->
<ion-spinner [hidden]="preferences.disableall ||

View File

@ -86,7 +86,7 @@ export type AddonMessagesOfflineMessagesDBRecord = {
deviceoffline: number; // If message was stored because device was offline.
};
export type AddonMessagesOfflineConversationMessagesDBRecord = {
export type AddonMessagesOfflineConversationMessagesDBRecord = {
conversationid: number;
text: string;
timecreated: number;

View File

@ -1165,7 +1165,7 @@ export class AddonMessagesProvider {
canLoadMore: false,
};
const preSets: CoreSiteWSPreSets = {
const preSets: CoreSiteWSPreSets = {
cacheKey: this.getCacheKeyForDiscussion(userId),
};
const params: AddonMessagesGetMessagesWSParams = {
@ -2012,7 +2012,7 @@ export class AddonMessagesProvider {
* Returns whether or not we can mark all messages as read.
*
* @return If related WS is available on current site.
* @since 3.2
* @since 3.2
*/
isMarkAllMessagesReadEnabled(): boolean {
return CoreSites.wsAvailableInCurrentSite('core_message_mark_all_conversation_messages_as_read') ||
@ -2023,7 +2023,7 @@ export class AddonMessagesProvider {
* Returns whether or not we can count unread messages.
*
* @return True if enabled, false otherwise.
* @since 3.2
* @since 3.2
*/
isMessageCountEnabled(): boolean {
return CoreSites.wsAvailableInCurrentSite('core_message_get_unread_conversations_count');
@ -2033,7 +2033,7 @@ export class AddonMessagesProvider {
* Returns whether or not the message preferences are enabled for the current site.
*
* @return True if enabled, false otherwise.
* @since 3.2
* @since 3.2
*/
isMessagePreferencesEnabled(): boolean {
return CoreSites.wsAvailableInCurrentSite('core_message_get_user_message_preferences');
@ -2100,7 +2100,7 @@ export class AddonMessagesProvider {
/**
* Returns whether or not we can search messages.
*
* @since 3.2
* @since 3.2
*/
isSearchMessagesEnabled(): boolean {
return CoreSites.wsAvailableInCurrentSite('core_message_data_for_messagearea_search_messages');
@ -2167,7 +2167,7 @@ export class AddonMessagesProvider {
conversationid: conversationId,
};
const preSets: CoreSiteWSPreSets = {
const preSets: CoreSiteWSPreSets = {
responseExpected: false,
};
@ -2187,7 +2187,7 @@ export class AddonMessagesProvider {
useridfrom: userIdFrom,
};
const preSets: CoreSiteWSPreSets = {
const preSets: CoreSiteWSPreSets = {
typeExpected: 'boolean',
};
@ -2834,7 +2834,7 @@ export class AddonMessagesProvider {
* @param discussions List of discussions.
* @param siteId Site ID. If not defined, current site.
*/
protected storeUsersFromDiscussions(discussions: { [userId: number]: AddonMessagesDiscussion }, siteId?: string): void {
protected storeUsersFromDiscussions(discussions: { [userId: number]: AddonMessagesDiscussion }, siteId?: string): void {
const users: CoreUserBasicData[] = [];
for (const userId in discussions) {
@ -3377,7 +3377,7 @@ export type AddonMessagesMarkMessageReadResult = {
* Result of WS core_message_send_instant_messages.
*/
export type AddonMessagesSendInstantMessagesMessage = {
msgid: number; // Test this to know if it succeeds: id of the created message if it succeeded, -1 when failed.
msgid: number; // Test this to know if it succeeds: i of the created message if it succeeded, -1 when failed.
clientmsgid?: string; // Your own id for the message.
errormessage?: string; // Error message - if it failed.
text?: string; // @since 3.6. The text of the message.

View File

@ -14,7 +14,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600"
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600"
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon"
[closeOnClick]="false">
</core-context-menu-item>

View File

@ -601,7 +601,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
disabled: false,
};
this.originalGrades = {
this.originalGrades = {
addAttempt: false,
applyToAll: false,
outcomes: {},
@ -613,7 +613,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
// If we have data about the grader, get its profile.
if (feedback.grade && feedback.grade.grader > 0) {
try {
this.grader = await CoreUser.getProfile(feedback.grade.grader, this.courseId);
this.grader = await CoreUser.getProfile(feedback.grade.grader, this.courseId);
} catch {
// Ignore errors.
}

View File

@ -4,7 +4,7 @@
<ion-back-button [text]="'core.back' | translate"></ion-back-button>
</ion-buttons>
<ion-title>
<core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId">
<core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId">
</core-format-text>
</ion-title>

View File

@ -54,7 +54,7 @@ export class AddonModAssignSubmissionListPage implements AfterViewInit, OnDestro
assign?: AddonModAssignAssign; // Assignment.
submissions: AddonModAssignSubmissionListManager; // List of submissions
loaded = false; // Whether data has been loaded.
haveAllParticipants = true; // Whether all participants have been loaded.
haveAllParticipants = true; // Whether all participants have been loaded.
groupId = 0; // Group ID to show.
courseId!: number; // Course ID the assignment belongs to.
moduleId!: number; // Module ID the submission belongs to.

View File

@ -37,7 +37,7 @@ export class AddonModAssignSubmissionReviewPage implements OnInit, CanLeave {
title = ''; // Title to display.
moduleId!: number; // Module ID the submission belongs to.
courseId!: number; // Course ID the assignment belongs to.
submitId!: number; // User that did the submission.
submitId!: number; // User that did the submission.
blindId?: number; // Blinded user ID (if it's blinded).
loaded = false; // Whether data has been loaded.
canSaveGrades = false; // Whether the user can save grades.

View File

@ -464,7 +464,7 @@ export class AddonModAssignSyncProvider extends CoreCourseActivitySyncBaseProvid
// Override offline grade and outcomes based on the gradebook data.
grades.forEach((grade: CoreGradesFormattedItem | CoreGradesFormattedRow) => {
if ('gradedategraded' in grade && (grade.gradedategraded || 0) >= offlineData.timemodified) {
if ('gradedategraded' in grade && (grade.gradedategraded || 0) >= offlineData.timemodified) {
if (!grade.outcomeid && !grade.scaleid) {
if (gradeInfo && gradeInfo.scale) {
offlineData.grade = this.getSelectedScaleId(gradeInfo.scale, grade.grade || '');

View File

@ -90,7 +90,7 @@ export class AddonModAssignProvider {
static readonly SUBMITTED_FOR_GRADING_EVENT = 'addon_mod_assign_submitted_for_grading';
static readonly GRADED_EVENT = 'addon_mod_assign_graded';
protected gradingOfflineEnabled: {[siteId: string]: boolean} = {};
protected gradingOfflineEnabled: {[siteId: string]: boolean} = {};
/**
* Check if the user can submit in offline. This should only be used if submissionStatus.lastattempt.cansubmit cannot
@ -1302,7 +1302,7 @@ export class AddonModAssignProvider {
);
return true;
} catch (error) {
} catch (error) {
if (error && !CoreUtils.isWebServiceError(error)) {
// Couldn't connect to server, store in offline.
return storeOffline();

View File

@ -79,7 +79,7 @@ export class AddonModAssignSubmissionFileComponent extends AddonModAssignSubmiss
// No offline data, get the online files.
this.files = AddonModAssign.getSubmissionPluginAttachments(this.plugin);
}
} finally {
} finally {
CoreFileSession.setFiles(this.component, this.assign.id, this.files);
}
}

View File

@ -12,7 +12,7 @@
<nav>
<ion-list>
<ion-item class="ion-text-wrap" *ngFor="let chapter of chapters" (click)="loadChapter(chapter.id)"
[attr.aria-current]="selected == chapter.id ? 'page' : 'false'" button
[attr.aria-current]="selected == chapter.id ? 'page' : 'false'" button
[class.item-dimmed]="chapter.hidden">
<ion-label>
<p [class.ion-padding-left]="addPadding && chapter.level == 1 ? true : null">

View File

@ -33,8 +33,8 @@ export class AddonModBookIndexLinkHandlerService extends CoreContentLinksModuleI
/**
* Get the mod params necessary to open an activity.
*
* @param url The URL to treat.
* @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
* @param url The URL to treat.
* @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
* @return List of params to pass to navigateToModule / navigateToModuleByInstance.
*/
getPageParams(url: string, params: Record<string, string>): Params {

View File

@ -13,7 +13,7 @@
<core-context-menu-item *ngIf="loaded && isOnline" [priority]="700" [content]="'core.refresh' | translate"
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600"
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600"
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon"
[closeOnClick]="false">
</core-context-menu-item>

View File

@ -201,7 +201,7 @@ export class AddonModChatChatPage implements OnInit, OnDestroy {
/**
* Get the user fullname for a beep.
*
* @param id User Id before parsing.
* @param id User Id before parsing.
* @return User fullname.
*/
protected async getUserFullname(id: string): Promise<string> {

View File

@ -120,7 +120,7 @@ export class AddonModChatSessionMessagesPage implements OnInit {
return user.fullname;
} catch {
// Error getting profile.
return id;
return id;
}
}

View File

@ -109,7 +109,7 @@ export class AddonModChatHelperProvider {
/**
* Check if the date should be displayed between messages (when the day changes at midnight for example).
*
* @param message New message object.
* @param message New message object.
* @param prevMessage Previous message object.
* @return True if messages are from diferent days, false othetwise.
*/

View File

@ -13,7 +13,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
[content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"

View File

@ -346,7 +346,7 @@ export class AddonModChoiceProvider {
async invalidateOptions(choiceId: number, siteId?: string): Promise<void> {
const site = await CoreSites.getSite(siteId);
await site.invalidateWsCacheForKey(this.getChoiceOptionsCacheKey(choiceId));
await site.invalidateWsCacheForKey(this.getChoiceOptionsCacheKey(choiceId));
}
/**
@ -359,7 +359,7 @@ export class AddonModChoiceProvider {
async invalidateResults(choiceId: number, siteId?: string): Promise<void> {
const site = await CoreSites.getSite(siteId);
await site.invalidateWsCacheForKey(this.getChoiceResultsCacheKey(choiceId));
await site.invalidateWsCacheForKey(this.getChoiceResultsCacheKey(choiceId));
}
/**

View File

@ -2,7 +2,7 @@
<ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
<ion-button *ngIf="action == 'edit'" fill="clear" (click)="editEntry()" [attr.aria-label]="'core.edit' | translate">
<ion-button *ngIf="action == 'edit'" fill="clear" (click)="editEntry()" [attr.aria-label]="'core.edit' | translate">
<ion-icon name="fas-cog" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
@ -27,8 +27,8 @@
component="mod_data" [itemId]="entry.id" area="database_entry" [courseId]="database.course">
</core-comments>
<span *ngIf="action == 'timeadded'">{{ entry.timecreated * 1000 | coreFormatDate }}</span>
<span *ngIf="action == 'timemodified'">{{ entry.timemodified * 1000 | coreFormatDate }}</span>
<span *ngIf="action == 'timeadded'">{{ entry.timecreated * 1000 | coreFormatDate }}</span>
<span *ngIf="action == 'timemodified'">{{ entry.timemodified * 1000 | coreFormatDate }}</span>
<a *ngIf="action == 'userpicture'" core-user-link [courseId]="database.course" [userId]="entry.userid" [title]="entry.fullname">
<img class="avatar-round" [src]="userPicture" [alt]="'core.pictureof' | translate:{$a: entry.fullname}" core-external-content

View File

@ -17,7 +17,7 @@
[content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon"
[closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="loaded && (hasOffline || hasOfflineRatings) && isOnline" [priority]="600"
<core-context-menu-item *ngIf="loaded && (hasOffline || hasOfflineRatings) && isOnline" [priority]="600"
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon"
[closeOnClick]="false">
</core-context-menu-item>

View File

@ -87,7 +87,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
hasNextPage = false;
entriesRendered = '';
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
jsData?: {
fields: Record<number, AddonModDataField>;

View File

@ -17,7 +17,7 @@
<ion-toggle [(ngModel)]="search.searchingAdvanced"></ion-toggle>
</ion-item>
<form (ngSubmit)="searchEntries($event)" [formGroup]="searchForm" #searchFormEl>
<ion-list class="ion-no-margin">
<ion-list class="ion-no-margin">
<ion-item [hidden]="search.searchingAdvanced">
<ion-label></ion-label>
<ion-input type="text" placeholder="{{ 'addon.mod_data.search' | translate}}"

View File

@ -49,7 +49,7 @@ export class AddonModDataSearchComponent implements OnInit {
advancedSearch = '';
advancedIndexed: CoreFormFields = {};
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
searchForm: FormGroup;
jsData?: {

View File

@ -22,8 +22,6 @@
.addon-data-advanced-search {
padding: 16px;
width: 100%;
// @todo check if needed
// @include safe-area-padding-horizontal(16px !important, 16px !important);
}
.addon-data-contents form,

View File

@ -17,8 +17,6 @@ $grid-column-paddings: (
white-space: normal;
word-break: break-word;
padding: 16px;
// @todo check if needed
// @include safe-area-padding-horizontal(16px !important, 16px !important);
background-color: var(--ion-item-background);
border-width: 1px 0;

View File

@ -93,7 +93,7 @@ export class AddonModDataFieldDateHandlerService implements AddonModDataFieldHan
{
fieldid: field.id,
subfield: 'year',
value: date[0],
value: date[0],
},
{
fieldid: field.id,

View File

@ -78,14 +78,14 @@ export class AddonModDataFieldFileHandlerService implements AddonModDataFieldHan
* @inheritdoc
*/
getFieldEditFiles(field: AddonModDataField): CoreFileEntry[] {
return CoreFileSession.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id);
return CoreFileSession.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id);
}
/**
* @inheritdoc
*/
hasFieldDataChanged(field: AddonModDataField, inputData: CoreFormFields, originalFieldData: AddonModDataEntryField): boolean {
const files = CoreFileSession.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id) || [];
const files = CoreFileSession.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id) || [];
let originalFiles = (originalFieldData && originalFieldData.files) || [];
if (originalFiles.length) {

View File

@ -146,7 +146,7 @@ export class AddonModDataFieldLatlongComponent extends AddonModDataFieldPluginCo
return;
}
CoreDomUtils.showErrorModalDefault(error, 'Error getting location');
CoreDomUtils.showErrorModalDefault(error, 'Error getting location');
}
/**

View File

@ -133,7 +133,7 @@ export class AddonModDataFieldPictureComponent extends AddonModDataFieldPluginCo
}
}, 1);
this.width = CoreDomUtils.formatPixelsSize(this.field.param1);
this.width = CoreDomUtils.formatPixelsSize(this.field.param1);
this.height = CoreDomUtils.formatPixelsSize(this.field.param2);
}
}

View File

@ -89,7 +89,7 @@ export class AddonModDataFieldPictureHandlerService implements AddonModDataField
* @inheritdoc
*/
getFieldEditFiles(field: AddonModDataField): CoreFileEntry[] {
return CoreFileSession.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id);
return CoreFileSession.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id);
}
/**

View File

@ -76,7 +76,7 @@ export class AddonModDataEditPage implements OnInit {
groupInfo?: CoreGroupInfo;
editFormRender = '';
editForm: FormGroup;
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
jsData?: {
fields: Record<number, AddonModDataField>;
database?: AddonModDataData;

View File

@ -77,7 +77,7 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy {
showComments = false;
entryHtml = '';
siteId: string;
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
jsData?: {
fields: Record<number, AddonModDataField>;
entries: Record<number, AddonModDataEntry>;

View File

@ -399,7 +399,7 @@ export class AddonModDataHelperProvider {
database: AddonModDataData,
accessInfo: AddonModDataGetDataAccessInformationWSResponse,
entry: AddonModDataEntry,
): Record<AddonModDataAction, boolean> {
): Record<AddonModDataAction, boolean> {
return {
add: false, // Not directly used on entries.
more: true,
@ -719,7 +719,7 @@ export class AddonModDataHelperProvider {
// Ignore errors.
}
CoreEvents.trigger(AddonModDataProvider.ENTRY_CHANGED, { dataId, entryId, deleted: true }, siteId);
CoreEvents.trigger(AddonModDataProvider.ENTRY_CHANGED, { dataId, entryId, deleted: true }, siteId);
CoreDomUtils.showToast('addon.mod_data.recorddeleted', true, 3000);

View File

@ -481,7 +481,7 @@ export type AddonModDataSyncResult = {
updated: boolean; // Whether some data was sent to the server or offline data was updated.
};
export type AddonModDataAutoSyncData = {
export type AddonModDataAutoSyncData = {
dataId: number;
warnings: string[];
entryId?: number;

View File

@ -635,7 +635,7 @@ export class AddonModDataProvider {
}
/**
* Get access information for a given database.
* Get access information for a given database.
*
* @param dataId Data ID.
* @param options Other options.
@ -1304,7 +1304,7 @@ type AddonModDataDeleteEntryWSParams = {
*/
type AddonModDataUpdateEntryWSParams = {
entryid: number; // The entry record id.
data: AddonModDataEntryWSField[]; // The fields data to be updated.
data: AddonModDataEntryWSField[]; // The fields data to be updated.
};
/**

View File

@ -13,7 +13,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
[content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"

View File

@ -38,7 +38,7 @@
<ion-label>
<h2 *ngIf="item.name" [core-mark-required]="item.required">
<span *ngIf="feedback!.autonumbering && item.itemnumber">{{item.itemnumber}}. </span>
<core-format-text [component]="component" [componentId]="cmId" [text]="item.name"
<core-format-text [component]="component" [componentId]="cmId" [text]="item.name"
contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId">
</core-format-text>
</h2>

View File

@ -75,7 +75,7 @@
[required]="item.required" name="{{item.typ}}_{{item.id}}">
<ion-item *ngFor="let option of item.choices">
<ion-label>
<core-format-text [component]="component" [componentId]="cmId"
<core-format-text [component]="component" [componentId]="cmId"
[text]="option.label" contextLevel="module" [contextInstanceId]="cmId"
[wsNotFiltered]="true" [courseId]="courseId">
</core-format-text>
@ -146,7 +146,7 @@
{{ 'addon.mod_feedback.feedback_submitted_offline' | translate }}
</p>
<p *ngIf="completionPageContents">
<core-format-text [component]="component" componentId="componentId" [text]="completionPageContents"
<core-format-text [component]="component" componentId="componentId" [text]="completionPageContents"
contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId">
</core-format-text>
</p>

View File

@ -12,7 +12,7 @@
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
</ion-refresher>
<core-loading [hideUntil]="loaded">
<ion-list class="ion-no-margin">
<ion-list class="ion-no-margin">
<ion-item class="ion-text-wrap" *ngIf="groupInfo && (groupInfo.separateGroups || groupInfo.visibleGroups)">
<ion-label id="addon-feedback-groupslabel">
<ng-container *ngIf="groupInfo.separateGroups">{{'core.groupsseparate' | translate }}</ng-container>

View File

@ -117,7 +117,7 @@ export class AddonModFeedbackHelperProvider {
if (itemData.typ == 'multichoice' || itemData.typ == 'multichoicerated') {
value = itemData.value || 0;
} else if (this.isNumericItem(itemData)) {
value = itemData.value || itemData.value == 0 ? itemData.value : '';
value = itemData.value || itemData.value == 0 ? itemData.value : '';
if (value != '') {
if ((itemData.rangefrom != '' && value < itemData.rangefrom) ||
@ -126,7 +126,7 @@ export class AddonModFeedbackHelperProvider {
}
}
} else {
value = itemData.value || itemData.value == 0 ? itemData.value : '';
value = itemData.value || itemData.value == 0 ? itemData.value : '';
}
answered = !!value;

View File

@ -511,7 +511,7 @@ export class AddonModFeedbackProvider {
}
/**
* Get access information for a given feedback.
* Get access information for a given feedback.
*
* @param feedbackId Feedback ID.
* @param options Other options.

View File

@ -255,7 +255,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
componentProps: {
post: this.post,
component: this.component,
componentId: this.componentId,
componentId: this.componentId,
forum: this.forum,
},
backdropDismiss: false,

View File

@ -12,7 +12,7 @@
<ion-list id="addon-mod-forum-sort-selector" role="listbox" aria-labelledby="addon-mod-forum-sort-order-label">
<ng-container *ngFor="let sortOrder of sortOrders">
<ion-item class="ion-text-wrap" detail="false" role="combobox"
[attr.aria-current]="selected == sortOrder.value ? 'page' : 'false'" [attr.aria-label]="sortOrder.label | translate"
[attr.aria-current]="selected == sortOrder.value ? 'page' : 'false'" [attr.aria-label]="sortOrder.label | translate"
(click)="selectSortOrder(sortOrder)" button aria-haspopup="dialog">
<ion-label>
<h2>{{ sortOrder.label | translate }}</h2>

View File

@ -89,7 +89,7 @@
</ion-item>
</ion-card>
<div *ngIf="startingPost" class="ion-margin-bottom">
<div *ngIf="startingPost" class="ion-margin-bottom">
<addon-mod-forum-post
[post]="startingPost" [discussion]="discussion" [courseId]="courseId" [highlight]="true"
[discussionId]="discussionId" [component]="component" [componentId]="cmId"

View File

@ -531,9 +531,9 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
/**
* Convenience function to load discussion.
*
* @param forumId Forum ID.
* @param cmId Forum cmid.
* @param discussionId Discussion ID.
* @param forumId Forum ID.
* @param cmId Forum cmid.
* @param discussionId Discussion ID.
* @return Promise resolved when done.
*/
protected async loadDiscussion(forumId: number, cmId: number, discussionId: number): Promise<void> {

View File

@ -465,7 +465,7 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy, CanLea
async add(): Promise<void> {
const forumName = this.forum.name;
const subject = this.newDiscussion.subject;
let message = this.newDiscussion.message || '';
let message = this.newDiscussion.message || '';
const pin = this.newDiscussion.pin;
const attachments = this.newDiscussion.files;
const discTimecreated = this.timeCreated || Date.now();

View File

@ -49,8 +49,6 @@ declare module '@singletons/events' {
/**
* Service that provides some features for forums.
*
* @todo Add all content.
*/
@Injectable({ providedIn: 'root' })
export class AddonModForumProvider {

View File

@ -145,7 +145,7 @@ export class AddonModForumModuleHandlerService implements CoreCourseModuleHandle
return;
}
data.extraBadge = Translate.instant('core.loading');
data.extraBadge = Translate.instant('core.loading');
data.extraBadgeColor = 'light';
await CoreUtils.ignoreErrors(AddonModForum.invalidateForumData(courseId));

View File

@ -12,7 +12,7 @@
<nav>
<ion-list>
<ion-item *ngFor="let item of items" (click)="loadItem(item.href)"
[attr.aria-current]="selected == item.href ? 'page' : 'false'" button>
[attr.aria-current]="selected == item.href ? 'page' : 'false'" button>
<ion-label [class.core-bold]="!item.href">
<span class="ion-padding-left" *ngFor="let i of getNumberForPadding(item.level)"></span>{{item.title}}
</ion-label>

View File

@ -144,7 +144,7 @@ export class AddonModImscpProvider {
* @return Cache key.
*/
protected getImscpDataCacheKey(courseId: number): string {
return ROOT_CACHE_KEY + 'imscp:' + courseId;
return ROOT_CACHE_KEY + 'imscp:' + courseId;
}
/**

View File

@ -13,7 +13,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
[content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"

View File

@ -195,7 +195,7 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo
this.preventReasons = [preventReason!];
lessonReady = false;
}
} else {
} else {
// Lesson cannot be started.
this.preventReasons = [preventReason!];
lessonReady = false;

View File

@ -884,7 +884,7 @@ export class AddonModLessonProvider {
// Answer found.
result.correctanswer = this.isAnswerCorrect(lesson, pageData.page!.id, answer, pageIndex);
result.newpageid = answer.jumpto || 0;
result.response = answer.response || '';
result.response = answer.response || '';
result.studentanswer = result.userresponse = answer.answer || '';
break;
}
@ -3195,7 +3195,7 @@ export class AddonModLessonProvider {
}
let nAttempts: number | undefined;
result.attemptsremaining = 0;
result.attemptsremaining = 0;
result.maxattemptsreached = false;
if (result.noanswer) {
@ -3902,7 +3902,7 @@ export type AddonModLessonGetPagesWSResponse = {
*/
export type AddonModLessonGetPagesPageWSData = {
page: AddonModLessonPageWSData; // Page fields.
answerids: number[]; // List of answers ids (empty for content pages in Moodle 1.9).
answerids: number[]; // List of answers ids (empty for content pages in Moodle 1.9).
jumps: number[]; // List of possible page jumps.
filescount: number; // The total number of files attached to the page.
filessizetotal: number; // The total size of the files.

View File

@ -119,7 +119,7 @@ export class AddonModLtiModuleHandlerService implements CoreCourseModuleHandler
const siteId = CoreSites.getCurrentSiteId();
try {
await CoreFilepool.downloadUrl(siteId, icon, false, AddonModLtiProvider.COMPONENT, module.id);
await CoreFilepool.downloadUrl(siteId, icon, false, AddonModLtiProvider.COMPONENT, module.id);
// Get the internal URL.
const url = await CoreFilepool.getSrcByUrl(siteId, icon, AddonModLtiProvider.COMPONENT, module.id);

View File

@ -13,7 +13,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
[content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
@ -61,51 +61,62 @@
<!-- List of user attempts. -->
<ion-card class="addon-mod_quiz-table" *ngIf="quiz && attempts.length">
<ion-card-header class="ion-text-wrap">
<ion-card-header>
<ion-card-title>{{ 'addon.mod_quiz.summaryofattempts' | translate }}</ion-card-title>
</ion-card-header>
<ion-card-title>{{ 'addon.mod_quiz.summaryofattempts' | translate }}</ion-card-title>
</ion-card-header>
<ion-card-content>
<ion-card-content role="table">
<!-- "Header" of the table -->
<ion-item class="ion-text-wrap addon-mod_quiz-table-header" detail="true">
<ion-label>
<ion-row class="ion-align-items-center">
<ion-col class="ion-text-center ion-hide-md-down" *ngIf="quiz.showAttemptColumn">
<strong>{{ 'addon.mod_quiz.attemptnumber' | translate }}</strong>
<ion-item class="ion-text-wrap addon-mod_quiz-table-header">
<ion-label role="rowgroup">
<ion-row class="ion-align-items-center" role="row">
<ion-col class="ion-text-center" *ngIf="quiz.showAttemptColumn" role="columnheader">
<strong class="ion-hide-md-up" aria-hidden="true">#</strong>
<span class="sr-only ion-hide-md-up">{{ 'addon.mod_quiz.attemptnumber' | translate }}</span>
<strong class="ion-hide-md-down">{{ 'addon.mod_quiz.attemptnumber' | translate }}</strong>
</ion-col>
<ion-col class="ion-text-center ion-hide-md-up" *ngIf="quiz.showAttemptColumn"><strong>#</strong></ion-col>
<ion-col size="7"><strong>{{ 'addon.mod_quiz.attemptstate' | translate }}</strong></ion-col>
<ion-col class="ion-text-center ion-hide-md-down" *ngIf="quiz.showMarkColumn">
<ion-col size="7" role="columnheader">
<strong>{{ 'addon.mod_quiz.attemptstate' | translate }}</strong>
</ion-col>
<ion-col class="ion-text-center ion-hide-md-down" *ngIf="quiz.showMarkColumn" role="columnheader">
<strong>{{ 'addon.mod_quiz.marks' | translate }} / {{ quiz.sumGradesFormatted }}</strong>
</ion-col>
<ion-col class="ion-text-center" *ngIf="quiz.showGradeColumn">
<ion-col class="ion-text-center" *ngIf="quiz.showGradeColumn" role="columnheader">
<strong>{{ 'addon.mod_quiz.grade' | translate }} / {{ quiz.gradeFormatted }}</strong>
</ion-col>
</ion-row>
</ion-label>
</ion-item>
<!-- List of attempts. -->
<ion-item class="ion-text-wrap" *ngFor="let attempt of attempts" button detail="true"
[ngClass]='{"addon-mod_quiz-highlighted": attempt.highlightGrade}'
[attr.aria-label]="'core.seemoredetail' | translate" (click)="viewAttempt(attempt.id)">
<ion-label>
<ion-row class="ion-align-items-center">
<ion-col class="ion-text-center" *ngIf="quiz.showAttemptColumn && attempt.preview">
{{ 'addon.mod_quiz.preview' | translate }}
</ion-col>
<ion-col class="ion-text-center" *ngIf="quiz.showAttemptColumn && !attempt.preview">
{{ attempt.attempt }}
</ion-col>
<ion-col size="7">
<p *ngFor="let sentence of attempt.readableState">{{ sentence }}</p>
</ion-col>
<ion-col class="ion-text-center ion-hide-md-down" *ngIf="quiz.showMarkColumn">
<p>{{ attempt.readableMark }}</p>
</ion-col>
<ion-col class="ion-text-center" *ngIf="quiz.showGradeColumn"><p>{{ attempt.readableGrade }}</p></ion-col>
</ion-row>
</ion-label>
</ion-item>
<div role="rowgroup">
<!-- List of attempts. -->
<ion-item
button
detail="true"
*ngFor="let attempt of attempts"
class="ion-text-wrap"
[ngClass]='{"addon-mod_quiz-highlighted": attempt.highlightGrade}'
[attr.aria-label]="'core.seemoredetail' | translate"
(click)="viewAttempt(attempt.id)"
>
<ion-label>
<ion-row class="ion-align-items-center" role="row">
<ion-col class="ion-text-center" *ngIf="quiz.showAttemptColumn && attempt.preview" role="cell">
{{ 'addon.mod_quiz.preview' | translate }}
</ion-col>
<ion-col class="ion-text-center" *ngIf="quiz.showAttemptColumn && !attempt.preview" role="cell">
{{ attempt.attempt }}
</ion-col>
<ion-col size="7" role="cell">
<p *ngFor="let sentence of attempt.readableState">{{ sentence }}</p>
</ion-col>
<ion-col class="ion-text-center ion-hide-md-down" *ngIf="quiz.showMarkColumn" role="cell">
<p>{{ attempt.readableMark }}</p>
</ion-col>
<ion-col class="ion-text-center" *ngIf="quiz.showGradeColumn" role="cell">
<p>{{ attempt.readableGrade }}</p>
</ion-col>
</ion-row>
</ion-label>
</ion-item>
</div>
</ion-card-content>
</ion-card>

View File

@ -23,8 +23,8 @@
<ion-card *ngIf="attempt">
<ion-card-header class="ion-text-wrap">
<ion-card-title>
<span *ngIf="attempt.preview">{{ 'addon.mod_quiz.reviewofpreview' | translate }}</span>
<span *ngIf="!attempt.preview">{{ 'addon.mod_quiz.reviewofattempt' | translate:{$a: attempt.attempt} }}</span>
<ng-container *ngIf="attempt.preview">{{ 'addon.mod_quiz.reviewofpreview' | translate }}</ng-container>
<ng-container *ngIf="!attempt.preview">{{ 'addon.mod_quiz.reviewofattempt' | translate:{$a: attempt.attempt} }}</ng-container>
</ion-card-title>
</ion-card-header>
<ion-list lines="none">

View File

@ -176,7 +176,7 @@ export class AddonModQuizHelperProvider {
throw new CoreCanceledError();
}
return modalData;
return modalData;
}
/**

View File

@ -2042,7 +2042,7 @@ export type AddonModQuizAttemptWSData = {
timefinish?: number; // Time when the attempt was submitted. 0 if the attempt has not been submitted yet.
timemodified?: number; // Last modified time.
timemodifiedoffline?: number; // Last modified time via webservices.
timecheckstate?: number; // Next time quiz cron should check attempt for state changes. NULL means never check.
timecheckstate?: number; // Next time quiz cron should check attempt for state changes. NULL means never check.
sumgrades?: number | null; // Total marks for this attempt.
};

View File

@ -13,7 +13,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
[content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"

View File

@ -31,7 +31,7 @@
<ng-container *ngFor="let sco of toc">
<ion-item *ngIf="sco.isvisible" class="ion-text-wrap" [detail]="sco.prereq && sco.launch"
[ngClass]="'core-padding-' + sco.level + ' addon-mod_scorm-type-' + sco.scormtype"
[attr.aria-current]="selected == sco.id ? 'page' : 'false'" (click)="loadSco(sco)"
[attr.aria-current]="selected == sco.id ? 'page' : 'false'" (click)="loadSco(sco)"
[disabled]="!sco.prereq || !sco.launch ? true : null" [button]="sco.prereq && sco.launch">
<ion-icon *ngIf="sco.icon" [name]="sco.icon.icon" [attr.aria-label]="sco.icon.description" slot="start">
</ion-icon>

View File

@ -893,7 +893,7 @@ export class AddonModScormProvider {
const data = await this.getScormUserData(scormId, attempt, userDataOptions);
const trackDataBySCO: Record<string, Record<string, AddonModScormDataValue>> = {};
const trackDataBySCO: Record<string, Record<string, AddonModScormDataValue>> = {};
// First populate trackDataBySCO to index by SCO identifier.
// We want the full list first because it's needed by evalPrerequisites.

View File

@ -13,7 +13,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600"
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600"
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)"
[iconAction]="syncIcon" [closeOnClick]="false">
</core-context-menu-item>

View File

@ -21,7 +21,7 @@
<ion-label><h2>{{ letter.label }}</h2></ion-label>
</ion-item-divider>
<ion-item class="ion-text-wrap" *ngFor="let page of letter.pages" (click)="goToPage(page)"
[attr.aria-current]="selectedTitle == page.title ? 'page' : 'false'" button>
[attr.aria-current]="selectedTitle == page.title ? 'page' : 'false'" button>
<ion-icon name="fas-home" slot="start" *ngIf="page.firstpage" aria-hidden="true"></ion-icon>
<ion-label>
<core-format-text [text]="page.title" contextLevel="module" [contextInstanceId]="moduleId"

View File

@ -6,7 +6,7 @@
<ion-item class="ion-text-wrap" *ngFor="let subwiki of group.subwikis" (click)="openSubwiki(subwiki)"
[attr.disabled]="!subwiki.canedit && subwiki.id <= 0"
[button]="subwiki.canedit || subwiki.id > 0"
[attr.aria-current]="isSubwikiSelected(subwiki) ? 'page' : 'false'" detail="false">
[attr.aria-current]="isSubwikiSelected(subwiki) ? 'page' : 'false'" detail="false">
<ion-label>{{ subwiki.name }}</ion-label>
<ion-icon *ngIf="isSubwikiSelected(subwiki)" name="fas-check" slot="end" aria-hidden="true"></ion-icon>
</ion-item>

View File

@ -115,7 +115,7 @@ export class AddonModWorkshopAssessmentStrategyAccumulativeHandlerService implem
currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
form: AddonModWorkshopGetAssessmentFormDefinitionData,
): Promise<CoreFormFields> {
const data: CoreFormFields = {};
const data: CoreFormFields = {};
const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
let hasErrors = false;
@ -135,7 +135,7 @@ export class AddonModWorkshopAssessmentStrategyAccumulativeHandlerService implem
data['gradeid__idx_' + idx] = parseInt(form.current[idx].gradeid, 10) || 0;
data['dimensionid__idx_' + idx] = parseInt(field.dimensionid, 10);
data['weight__idx_' + idx] = parseInt(field.weight, 10) || 0;
data['weight__idx_' + idx] = parseInt(field.weight, 10) || 0;
}
});

View File

@ -94,7 +94,7 @@ export class AddonModWorkshopAssessmentStrategyCommentsHandlerService implements
currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
form: AddonModWorkshopGetAssessmentFormDefinitionData,
): Promise<CoreFormFields> {
const data: CoreFormFields = {};
const data: CoreFormFields = {};
const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
let hasErrors = false;

View File

@ -66,7 +66,7 @@ export class AddonModWorkshopAssessmentStrategyNumErrorsHandlerService implement
originalValues[n] = {};
originalValues[n].peercomment = form.current[n].peercomment || '';
originalValues[n].number = field.number; // eslint-disable-line id-blacklist
originalValues[n].grade = form.current[n].grade || '';
originalValues[n].grade = form.current[n].grade || '';
});
return originalValues;
@ -98,7 +98,7 @@ export class AddonModWorkshopAssessmentStrategyNumErrorsHandlerService implement
currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
form: AddonModWorkshopGetAssessmentFormDefinitionData,
): Promise<CoreFormFields> {
const data: CoreFormFields = {};
const data: CoreFormFields = {};
const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
let hasErrors = false;
@ -118,7 +118,7 @@ export class AddonModWorkshopAssessmentStrategyNumErrorsHandlerService implement
data['gradeid__idx_' + idx] = parseInt(form.current[idx].gradeid, 10) || 0;
data['dimensionid__idx_' + idx] = parseInt(field.dimensionid, 10);
data['weight__idx_' + idx] = parseInt(field.weight, 10) || 0;
data['weight__idx_' + idx] = parseInt(field.weight, 10) || 0;
}
});

View File

@ -94,7 +94,7 @@ export class AddonModWorkshopAssessmentStrategyRubricHandlerService implements A
currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
form: AddonModWorkshopGetAssessmentFormDefinitionData,
): Promise<CoreFormFields> {
const data: CoreFormFields = {};
const data: CoreFormFields = {};
const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
let hasErrors = false;

View File

@ -13,7 +13,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
</core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600"
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600"
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon"
[closeOnClick]="false">
</core-context-menu-item>

View File

@ -14,7 +14,7 @@
<ion-content>
<ion-list>
<ng-container *ngFor="let phase of phases">
<ion-item-divider [attr.aria-current]="workshopPhase == phase.code ? 'page' : 'false'">
<ion-item-divider [attr.aria-current]="workshopPhase == phase.code ? 'page' : 'false'">
<ion-label>
<h2>{{ phase.title }}</h2>
<p class="ion-text-wrap" *ngIf="workshopPhase == phase.code">

View File

@ -32,7 +32,7 @@
</span>
</ion-label>
<core-rich-text-editor [control]="editForm.controls['content']" name="content"
[placeholder]="'addon.mod_workshop.submissioncontent' | translate" name="content" [component]="component"
[placeholder]="'addon.mod_workshop.submissioncontent' | translate" name="content" [component]="component"
[componentId]="componentId" [autoSave]="true" contextLevel="module" [contextInstanceId]="module.id"
elementId="content_editor" [draftExtraParams]="editorExtraParams"></core-rich-text-editor>
</ion-item>

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