commit
7a2c27fe57
|
@ -310,7 +310,7 @@ function array_contains {
|
|||
|
||||
|
||||
print_title 'Generating language from code...'
|
||||
gulp lang
|
||||
npx gulp lang
|
||||
|
||||
print_title 'Getting languages'
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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]">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -531,7 +531,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
|
|||
|
||||
try {
|
||||
await AddonCalendarHelper.refreshAfterChangeEvent(result.event, numberOfRepetitions);
|
||||
} catch {
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 || '');
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -120,7 +120,7 @@ export class AddonModChatSessionMessagesPage implements OnInit {
|
|||
return user.fullname;
|
||||
} catch {
|
||||
// Error getting profile.
|
||||
return id;
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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)"
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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}}"
|
||||
|
|
|
@ -49,7 +49,7 @@ export class AddonModDataSearchComponent implements OnInit {
|
|||
|
||||
advancedSearch = '';
|
||||
advancedIndexed: CoreFormFields = {};
|
||||
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
|
||||
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
|
||||
|
||||
searchForm: FormGroup;
|
||||
jsData?: {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -93,7 +93,7 @@ export class AddonModDataFieldDateHandlerService implements AddonModDataFieldHan
|
|||
{
|
||||
fieldid: field.id,
|
||||
subfield: 'year',
|
||||
value: date[0],
|
||||
value: date[0],
|
||||
},
|
||||
{
|
||||
fieldid: field.id,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -146,7 +146,7 @@ export class AddonModDataFieldLatlongComponent extends AddonModDataFieldPluginCo
|
|||
return;
|
||||
}
|
||||
|
||||
CoreDomUtils.showErrorModalDefault(error, 'Error getting location');
|
||||
CoreDomUtils.showErrorModalDefault(error, 'Error getting location');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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)"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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)"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -176,7 +176,7 @@ export class AddonModQuizHelperProvider {
|
|||
throw new CoreCanceledError();
|
||||
}
|
||||
|
||||
return modalData;
|
||||
return modalData;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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.
|
||||
};
|
||||
|
||||
|
|
|
@ -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)"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue