commit
7a2c27fe57
|
@ -310,7 +310,7 @@ function array_contains {
|
||||||
|
|
||||||
|
|
||||||
print_title 'Generating language from code...'
|
print_title 'Generating language from code...'
|
||||||
gulp lang
|
npx gulp lang
|
||||||
|
|
||||||
print_title 'Getting languages'
|
print_title 'Getting languages'
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,9 @@ DEFAULT_LASTVERSION='4.0'
|
||||||
|
|
||||||
# Checks if AWS is available and configured.
|
# Checks if AWS is available and configured.
|
||||||
function check_aws {
|
function check_aws {
|
||||||
aws --version &> /dev/null
|
|
||||||
AWS_SERVICE=1
|
AWS_SERVICE=1
|
||||||
|
|
||||||
|
aws --version &> /dev/null
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
AWS_SERVICE=0
|
AWS_SERVICE=0
|
||||||
echo 'AWS not installed. Check https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html for more info.'
|
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
|
fi
|
||||||
|
|
||||||
# In order to login to AWS, use credentials file or AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY vars.
|
# 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
|
AWS_SERVICE=0
|
||||||
lastversion=$DEFAULT_LASTVERSION
|
lastversion=$DEFAULT_LASTVERSION
|
||||||
echo 'AWS Cannot authenticate. Use aws configure or set the proper env vars.'
|
echo 'AWS Cannot authenticate. Use aws configure or set the proper env vars.'
|
||||||
|
@ -63,6 +64,13 @@ function get_last_version {
|
||||||
lastversion=$DEFAULT_LASTVERSION
|
lastversion=$DEFAULT_LASTVERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Create langfolder
|
||||||
|
function create_langfolder {
|
||||||
|
if [ ! -d $LANGPACKSFOLDER ]; then
|
||||||
|
mkdir $LANGPACKSFOLDER
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Get all language list from AWS.
|
# Get all language list from AWS.
|
||||||
function get_all_languages_aws {
|
function get_all_languages_aws {
|
||||||
langsfiles=`aws s3 ls s3://$BUCKET/$lastversion/`
|
langsfiles=`aws s3 ls s3://$BUCKET/$lastversion/`
|
||||||
|
@ -87,6 +95,8 @@ function get_language {
|
||||||
|
|
||||||
get_last_version
|
get_last_version
|
||||||
|
|
||||||
|
create_langfolder
|
||||||
|
|
||||||
echo "Getting $lang language"
|
echo "Getting $lang language"
|
||||||
|
|
||||||
pushd $LANGPACKSFOLDER > /dev/null
|
pushd $LANGPACKSFOLDER > /dev/null
|
||||||
|
@ -115,7 +125,7 @@ function get_languages {
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
mkdir $LANGPACKSFOLDER
|
create_langfolder
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,11 @@
|
||||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<core-loading [hideUntil]="badges.loaded">
|
<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">
|
[message]="'addon.badges.nobadges' | translate">
|
||||||
</core-empty-box>
|
</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"
|
<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)">
|
(click)="badges.select(badge)" [attr.aria-current]="badges.getItemAriaCurrent(badge)">
|
||||||
<ion-avatar slot="start">
|
<ion-avatar slot="start">
|
||||||
|
|
|
@ -34,8 +34,6 @@ export class AddonBlockLearningPlansHandlerService extends CoreBlockBaseHandler
|
||||||
* @return Data or promise resolved with the data.
|
* @return Data or promise resolved with the data.
|
||||||
*/
|
*/
|
||||||
getDisplayData(): CoreBlockHandlerData {
|
getDisplayData(): CoreBlockHandlerData {
|
||||||
// @todo
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: 'addon.block_learningplans.pluginname',
|
title: 'addon.block_learningplans.pluginname',
|
||||||
class: 'addon-block-learning-plans',
|
class: 'addon-block-learning-plans',
|
||||||
|
|
|
@ -327,8 +327,8 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
|
||||||
/**
|
/**
|
||||||
* Helper function to help with filter values.
|
* Helper function to help with filter values.
|
||||||
*
|
*
|
||||||
* @param showCondition If true, filter will be shown.
|
* @param showCondition If true, filter will be shown.
|
||||||
* @param disabledCondition If true, and showCondition is also met, it will be shown as disabled.
|
* @param disabledCondition If true, and showCondition is also met, it will be shown as disabled.
|
||||||
* @return show / disabled / hidden value.
|
* @return show / disabled / hidden value.
|
||||||
*/
|
*/
|
||||||
protected getShowFilterValue(showCondition: boolean, disabledCondition: boolean): string {
|
protected getShowFilterValue(showCondition: boolean, disabledCondition: boolean): string {
|
||||||
|
@ -507,7 +507,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
|
||||||
courses.forEach((course) => {
|
courses.forEach((course) => {
|
||||||
if (course.hidden) {
|
if (course.hidden) {
|
||||||
this.courses.hidden.push(course);
|
this.courses.hidden.push(course);
|
||||||
} else {
|
} else {
|
||||||
this.courses.all.push(course);
|
this.courses.all.push(course);
|
||||||
|
|
||||||
if ((course.enddate && course.enddate < today) || course.completed) {
|
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';
|
import { makeSingleton } from '@singletons';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Block handler.
|
* Block handler.
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonBlockMyOverviewHandlerService extends CoreBlockBaseHandler {
|
export class AddonBlockMyOverviewHandlerService extends CoreBlockBaseHandler {
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
.addon-calendar-navigation {
|
.addon-calendar-navigation {
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addon-calendar-months {
|
.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 *ngIf="!filteredEvents || !filteredEvents.length" icon="fas-calendar" [message]="'addon.calendar.noevents' | translate">
|
||||||
</core-empty-box>
|
</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">
|
<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
|
<ion-item class="ion-text-wrap addon-calendar-event" [attr.aria-label]="event.name" (click)="eventClicked(event)" button
|
||||||
[ngClass]="['addon-calendar-eventtype-'+event.eventtype]">
|
[ngClass]="['addon-calendar-eventtype-'+event.eventtype]">
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<core-context-menu-item *ngIf="!isCurrentDay" [priority]="900" [content]="'addon.calendar.today' | translate"
|
<core-context-menu-item *ngIf="!isCurrentDay" [priority]="900" [content]="'addon.calendar.today' | translate"
|
||||||
iconAction="fas-calendar-day" (action)="goToCurrentDay()">
|
iconAction="fas-calendar-day" (action)="goToCurrentDay()">
|
||||||
</core-context-menu-item>
|
</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)"
|
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event)"
|
||||||
[iconAction]="syncIcon" [closeOnClick]="false">
|
[iconAction]="syncIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
[message]="'addon.calendar.noevents' | translate">
|
[message]="'addon.calendar.noevents' | translate">
|
||||||
</core-empty-box>
|
</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">
|
<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)"
|
<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>
|
[class.item-dimmed]="event.ispast" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]" button>
|
||||||
|
|
|
@ -531,7 +531,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await AddonCalendarHelper.refreshAfterChangeEvent(result.event, numberOfRepetitions);
|
await AddonCalendarHelper.refreshAfterChangeEvent(result.event, numberOfRepetitions);
|
||||||
} catch {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ng-container *ngFor="let reminder of reminders">
|
<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!">
|
[class.item-dimmed]="(reminder.time == -1 ? (event.timestart - defaultTime) : reminder.time) <= currentTime!">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<p *ngIf="reminder.time == -1">
|
<p *ngIf="reminder.time == -1">
|
||||||
|
|
|
@ -343,8 +343,8 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
|
||||||
const minute = Math.floor(currentTime / 60) * 60;
|
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.
|
// Check if the notification time is in the same minute as we are, so the notification is triggered.
|
||||||
if (notificationTime >= minute && notificationTime < minute + 60) {
|
if (notificationTime >= minute && notificationTime < minute + 60) {
|
||||||
notificationTime = currentTime + 1;
|
notificationTime = currentTime + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
await AddonCalendar.addEventReminder(this.event, notificationTime);
|
await AddonCalendar.addEventReminder(this.event, notificationTime);
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<core-context-menu-item [hidden]="!notificationsEnabled" [priority]="600"
|
<core-context-menu-item [hidden]="!notificationsEnabled" [priority]="600"
|
||||||
[content]="'core.settings.settings' | translate" (action)="openSettings()" iconAction="fas-cogs">
|
[content]="'core.settings.settings' | translate" (action)="openSettings()" iconAction="fas-cogs">
|
||||||
</core-context-menu-item>
|
</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)"
|
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)"
|
||||||
[iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
[iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||||
</core-context-menu>
|
</core-context-menu>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<core-context-menu-item [hidden]="!notificationsEnabled" [priority]="600"
|
<core-context-menu-item [hidden]="!notificationsEnabled" [priority]="600"
|
||||||
[content]="'core.settings.settings' | translate" (action)="openSettings()" iconAction="fas-cogs">
|
[content]="'core.settings.settings' | translate" (action)="openSettings()" iconAction="fas-cogs">
|
||||||
</core-context-menu-item>
|
</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)"
|
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)"
|
||||||
[iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
[iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||||
</core-context-menu>
|
</core-context-menu>
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
[message]="'addon.calendar.noevents' | translate">
|
[message]="'addon.calendar.noevents' | translate">
|
||||||
</core-empty-box>
|
</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">
|
<ng-container *ngFor="let event of filteredEvents">
|
||||||
<ion-item-divider *ngIf="event.showDate">
|
<ion-item-divider *ngIf="event.showDate">
|
||||||
<ion-label><h2>{{ event.timestart * 1000 | coreFormatDate: "strftimedayshort" }}</h2></ion-label>
|
<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;
|
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));
|
this.shouldDisplayEvent(event, categories, courseId, categoryId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
|
||||||
id: event.id,
|
id: event.id,
|
||||||
repeatid: event.repeatid,
|
repeatid: event.repeatid,
|
||||||
timestart: event.timestart,
|
timestart: event.timestart,
|
||||||
repeated: data?.repeat ? (event as AddonCalendarEvent).eventcount || 1 : 1,
|
repeated: data?.repeat ? (event as AddonCalendarEvent).eventcount || 1 : 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -577,7 +577,7 @@ export class AddonCalendarProvider {
|
||||||
value = site.getStoredConfig('calendar_lookahead');
|
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.
|
* @param siteId ID of the site the event belongs to. If not defined, use current site.
|
||||||
* @return Promise resolved when stored.
|
* @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);
|
const site = await CoreSites.getSite(siteId);
|
||||||
siteId = site.getId();
|
siteId = site.getId();
|
||||||
try {
|
try {
|
||||||
|
@ -1775,7 +1775,7 @@ export const AddonCalendar = makeSingleton(AddonCalendarProvider);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data returned by calendar's events_exporter.
|
* 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 = {
|
export type AddonCalendarEvents = {
|
||||||
events: AddonCalendarEvent[]; // Events.
|
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 & {
|
export type AddonCalendarEvent = AddonCalendarEventBase & {
|
||||||
url: string; // Url.
|
url: string; // Url.
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
<ion-badge slot="end" color="success" *ngIf="userCompetency.proficiency">
|
<ion-badge slot="end" color="success" *ngIf="userCompetency.proficiency">
|
||||||
{{ 'core.yes' | translate }}
|
{{ 'core.yes' | translate }}
|
||||||
</ion-badge>
|
</ion-badge>
|
||||||
<ion-badge slot="end" color="danger" *ngIf="!userCompetency.proficiency">
|
<ion-badge slot="end" color="danger" *ngIf="!userCompetency.proficiency">
|
||||||
{{ 'core.no' | translate }}
|
{{ 'core.no' | translate }}
|
||||||
</ion-badge>
|
</ion-badge>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
@ -112,8 +112,8 @@
|
||||||
</ion-card>
|
</ion-card>
|
||||||
|
|
||||||
<div *ngIf="competency">
|
<div *ngIf="competency">
|
||||||
<h3 class="ion-margin-horizontal">{{ 'addon.competency.evidence' | translate }}</h3>
|
<h3 class="ion-margin-horizontal">{{ 'addon.competency.evidence' | translate }}</h3>
|
||||||
<p class="ion-margin-horizontal" *ngIf="competency.evidence.length == 0">
|
<p class="ion-margin-horizontal" *ngIf="competency.evidence.length == 0">
|
||||||
{{ 'addon.competency.noevidence' | translate }}
|
{{ 'addon.competency.noevidence' | translate }}
|
||||||
</p>
|
</p>
|
||||||
<ion-card *ngFor="let evidence of competency.evidence">
|
<ion-card *ngFor="let evidence of competency.evidence">
|
||||||
|
@ -128,7 +128,7 @@
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<p><ion-badge color="dark">{{ evidence.gradename }}</ion-badge></p>
|
<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>
|
<blockquote *ngIf="evidence.note">{{ evidence.note }}</blockquote>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ion-card>
|
</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 }}
|
{{ 'addon.competency.coursecompetencies' | translate }}
|
||||||
</h3>
|
</h3>
|
||||||
<ion-card *ngIf="user">
|
<ion-card *ngIf="user">
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
</ion-card>
|
</ion-card>
|
||||||
<ion-card *ngIf="plan">
|
<ion-card *ngIf="plan">
|
||||||
<ion-card-header class="ion-text-wrap">
|
<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-card-header>
|
||||||
<ion-list>
|
<ion-list>
|
||||||
<ion-item class="ion-text-wrap" *ngIf="plan.competencycount == 0">
|
<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 *ngIf="plans.empty" icon="fas-route" [message]="'addon.competency.noplanswerecreated' | translate">
|
||||||
|
|
||||||
</core-empty-box>
|
</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"
|
<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>
|
(click)="plans.select(plan)" [attr.aria-current]="plans.getItemAriaCurrent(plan)" button>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
:host-context([dir=rtl]) {
|
:host-context([dir=rtl]) {
|
||||||
.addon-messages-conversation-item,
|
.addon-messages-conversation-item,
|
||||||
.addon-message-discussion {
|
.addon-message-discussion {
|
||||||
h2 ion-icon {
|
h2 ion-icon {
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
<core-empty-box *ngIf="!hasContacts && searchString != ''" icon="fas-address-book"
|
<core-empty-box *ngIf="!hasContacts && searchString != ''" icon="fas-address-book"
|
||||||
[message]="'addon.messages.nousersfound' | translate"></core-empty-box>
|
[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)">
|
<ng-container *ngIf="contacts[contactType] && (contacts[contactType].length > 0 || contactType === searchType)">
|
||||||
<ion-item-divider>
|
<ion-item-divider>
|
||||||
<ion-label><h2>{{ 'addon.messages.type_' + contactType | translate }}</h2></ion-label>
|
<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"
|
<ion-item class="ion-text-wrap addon-messages-conversation-item"
|
||||||
*ngIf="contact.profileimageurl || contact.profileimageurlsmall"
|
*ngIf="contact.profileimageurl || contact.profileimageurlsmall"
|
||||||
[attr.aria-label]="contact.fullname" (click)="gotoDiscussion(contact.id)" detail="true" button
|
[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>
|
<core-user-avatar [user]="contact" slot="start" [checkOnline]="contact.showonlinestatus"></core-user-avatar>
|
||||||
<ion-label><h2>{{ contact.fullname }}</h2></ion-label>
|
<ion-label><h2>{{ contact.fullname }}</h2></ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
|
@ -25,10 +25,10 @@
|
||||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<core-loading [hideUntil]="confirmedLoaded" class="core-loading-center">
|
<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
|
<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"
|
*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"
|
<core-user-avatar slot="start" [user]="contact"
|
||||||
[checkOnline]="contact.showonlinestatus" [linkProfile]="false">
|
[checkOnline]="contact.showonlinestatus" [linkProfile]="false">
|
||||||
</core-user-avatar>
|
</core-user-avatar>
|
||||||
|
@ -62,10 +62,10 @@
|
||||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<core-loading [hideUntil]="requestsLoaded" class="core-loading-center">
|
<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"
|
<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-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>
|
<core-user-avatar slot="start" [user]="request" [linkProfile]="false"></core-user-avatar>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<core-format-text [text]="request.fullname" contextLevel="system" [contextInstanceId]="0">
|
<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.
|
// Fetch messages. Invalidate the cache before fetching.
|
||||||
if (this.groupMessagingEnabled) {
|
if (this.groupMessagingEnabled) {
|
||||||
await AddonMessages.invalidateConversationMessages(this.conversationId!);
|
await AddonMessages.invalidateConversationMessages(this.conversationId!);
|
||||||
messages = await this.getConversationMessages(this.pagesLoaded);
|
messages = await this.getConversationMessages(this.pagesLoaded);
|
||||||
} else {
|
} else {
|
||||||
await AddonMessages.invalidateDiscussionCache(this.userId!);
|
await AddonMessages.invalidateDiscussionCache(this.userId!);
|
||||||
messages = await this.getDiscussionMessages(this.pagesLoaded);
|
messages = await this.getDiscussionMessages(this.pagesLoaded);
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
</ion-item-divider>
|
</ion-item-divider>
|
||||||
<ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let result of search.results" button
|
<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-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>
|
<core-user-avatar [user]="result" slot="start" [checkOnline]="result.showonlinestatus"></core-user-avatar>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ result.fullname }}</h2>
|
<h2>{{ result.fullname }}</h2>
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
<ng-container *ngIf="!search.showResults">
|
<ng-container *ngIf="!search.showResults">
|
||||||
<ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let discussion of discussions" button
|
<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-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>
|
<core-user-avatar [user]="discussion" slot="start" checkOnline="false"></core-user-avatar>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ discussion.fullname }}</h2>
|
<h2>{{ discussion.fullname }}</h2>
|
||||||
|
|
|
@ -67,7 +67,7 @@ export class AddonMessagesDiscussions35Page implements OnInit, OnDestroy {
|
||||||
protected route: ActivatedRoute,
|
protected route: ActivatedRoute,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
this.search.loading = Translate.instant('core.searching');
|
this.search.loading = Translate.instant('core.searching');
|
||||||
this.loadingMessages = Translate.instant('core.loading');
|
this.loadingMessages = Translate.instant('core.loading');
|
||||||
this.siteId = CoreSites.getCurrentSiteId();
|
this.siteId = CoreSites.getCurrentSiteId();
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<core-split-view>
|
<core-split-view>
|
||||||
<core-search-box (onSubmit)="search($event)" (onClear)="clearSearch()" [disabled]="disableSearch" autocorrect="off"
|
<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">
|
<core-loading [hideUntil]="!displaySearching" [message]="'core.searching' | translate">
|
||||||
<ion-list *ngIf="displayResults">
|
<ion-list *ngIf="displayResults">
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
<!-- List of results -->
|
<!-- List of results -->
|
||||||
<ion-item class="addon-message-discussion ion-text-wrap" *ngFor="let result of item.results" [attr.aria-label]="result.fullname"
|
<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>
|
button>
|
||||||
<core-user-avatar slot="start" [user]="result" [checkOnline]="true" [linkProfile]="false"></core-user-avatar>
|
<core-user-avatar slot="start" [user]="result" [checkOnline]="true" [linkProfile]="false"></core-user-avatar>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
<ng-container *ngIf="!groupMessagingEnabled">
|
<ng-container *ngIf="!groupMessagingEnabled">
|
||||||
<!-- Tablet view -->
|
<!-- Tablet view -->
|
||||||
<ion-row class="ion-text-wrap ion-hide-md-down ion-align-items-center">
|
<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']">
|
<ion-col size="2" class="ion-text-center" *ngFor="let state of ['loggedin', 'loggedoff']">
|
||||||
<!-- If notifications not disabled, show toggle. -->
|
<!-- If notifications not disabled, show toggle. -->
|
||||||
<ion-spinner [hidden]="preferences.disableall ||
|
<ion-spinner [hidden]="preferences.disableall ||
|
||||||
|
|
|
@ -86,7 +86,7 @@ export type AddonMessagesOfflineMessagesDBRecord = {
|
||||||
deviceoffline: number; // If message was stored because device was offline.
|
deviceoffline: number; // If message was stored because device was offline.
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AddonMessagesOfflineConversationMessagesDBRecord = {
|
export type AddonMessagesOfflineConversationMessagesDBRecord = {
|
||||||
conversationid: number;
|
conversationid: number;
|
||||||
text: string;
|
text: string;
|
||||||
timecreated: number;
|
timecreated: number;
|
||||||
|
|
|
@ -1165,7 +1165,7 @@ export class AddonMessagesProvider {
|
||||||
canLoadMore: false,
|
canLoadMore: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const preSets: CoreSiteWSPreSets = {
|
const preSets: CoreSiteWSPreSets = {
|
||||||
cacheKey: this.getCacheKeyForDiscussion(userId),
|
cacheKey: this.getCacheKeyForDiscussion(userId),
|
||||||
};
|
};
|
||||||
const params: AddonMessagesGetMessagesWSParams = {
|
const params: AddonMessagesGetMessagesWSParams = {
|
||||||
|
@ -2012,7 +2012,7 @@ export class AddonMessagesProvider {
|
||||||
* Returns whether or not we can mark all messages as read.
|
* Returns whether or not we can mark all messages as read.
|
||||||
*
|
*
|
||||||
* @return If related WS is available on current site.
|
* @return If related WS is available on current site.
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
isMarkAllMessagesReadEnabled(): boolean {
|
isMarkAllMessagesReadEnabled(): boolean {
|
||||||
return CoreSites.wsAvailableInCurrentSite('core_message_mark_all_conversation_messages_as_read') ||
|
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.
|
* Returns whether or not we can count unread messages.
|
||||||
*
|
*
|
||||||
* @return True if enabled, false otherwise.
|
* @return True if enabled, false otherwise.
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
isMessageCountEnabled(): boolean {
|
isMessageCountEnabled(): boolean {
|
||||||
return CoreSites.wsAvailableInCurrentSite('core_message_get_unread_conversations_count');
|
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.
|
* Returns whether or not the message preferences are enabled for the current site.
|
||||||
*
|
*
|
||||||
* @return True if enabled, false otherwise.
|
* @return True if enabled, false otherwise.
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
isMessagePreferencesEnabled(): boolean {
|
isMessagePreferencesEnabled(): boolean {
|
||||||
return CoreSites.wsAvailableInCurrentSite('core_message_get_user_message_preferences');
|
return CoreSites.wsAvailableInCurrentSite('core_message_get_user_message_preferences');
|
||||||
|
@ -2100,7 +2100,7 @@ export class AddonMessagesProvider {
|
||||||
/**
|
/**
|
||||||
* Returns whether or not we can search messages.
|
* Returns whether or not we can search messages.
|
||||||
*
|
*
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
isSearchMessagesEnabled(): boolean {
|
isSearchMessagesEnabled(): boolean {
|
||||||
return CoreSites.wsAvailableInCurrentSite('core_message_data_for_messagearea_search_messages');
|
return CoreSites.wsAvailableInCurrentSite('core_message_data_for_messagearea_search_messages');
|
||||||
|
@ -2167,7 +2167,7 @@ export class AddonMessagesProvider {
|
||||||
conversationid: conversationId,
|
conversationid: conversationId,
|
||||||
};
|
};
|
||||||
|
|
||||||
const preSets: CoreSiteWSPreSets = {
|
const preSets: CoreSiteWSPreSets = {
|
||||||
responseExpected: false,
|
responseExpected: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2187,7 +2187,7 @@ export class AddonMessagesProvider {
|
||||||
useridfrom: userIdFrom,
|
useridfrom: userIdFrom,
|
||||||
};
|
};
|
||||||
|
|
||||||
const preSets: CoreSiteWSPreSets = {
|
const preSets: CoreSiteWSPreSets = {
|
||||||
typeExpected: 'boolean',
|
typeExpected: 'boolean',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2834,7 +2834,7 @@ export class AddonMessagesProvider {
|
||||||
* @param discussions List of discussions.
|
* @param discussions List of discussions.
|
||||||
* @param siteId Site ID. If not defined, current site.
|
* @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[] = [];
|
const users: CoreUserBasicData[] = [];
|
||||||
|
|
||||||
for (const userId in discussions) {
|
for (const userId in discussions) {
|
||||||
|
@ -3377,7 +3377,7 @@ export type AddonMessagesMarkMessageReadResult = {
|
||||||
* Result of WS core_message_send_instant_messages.
|
* Result of WS core_message_send_instant_messages.
|
||||||
*/
|
*/
|
||||||
export type AddonMessagesSendInstantMessagesMessage = {
|
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.
|
clientmsgid?: string; // Your own id for the message.
|
||||||
errormessage?: string; // Error message - if it failed.
|
errormessage?: string; // Error message - if it failed.
|
||||||
text?: string; // @since 3.6. The text of the message.
|
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"
|
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
|
||||||
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</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"
|
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon"
|
||||||
[closeOnClick]="false">
|
[closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
|
|
|
@ -601,7 +601,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
|
||||||
disabled: false,
|
disabled: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.originalGrades = {
|
this.originalGrades = {
|
||||||
addAttempt: false,
|
addAttempt: false,
|
||||||
applyToAll: false,
|
applyToAll: false,
|
||||||
outcomes: {},
|
outcomes: {},
|
||||||
|
@ -613,7 +613,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
|
||||||
// If we have data about the grader, get its profile.
|
// If we have data about the grader, get its profile.
|
||||||
if (feedback.grade && feedback.grade.grader > 0) {
|
if (feedback.grade && feedback.grade.grader > 0) {
|
||||||
try {
|
try {
|
||||||
this.grader = await CoreUser.getProfile(feedback.grade.grader, this.courseId);
|
this.grader = await CoreUser.getProfile(feedback.grade.grader, this.courseId);
|
||||||
} catch {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<ion-back-button [text]="'core.back' | translate"></ion-back-button>
|
<ion-back-button [text]="'core.back' | translate"></ion-back-button>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
<ion-title>
|
<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>
|
</core-format-text>
|
||||||
</ion-title>
|
</ion-title>
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ export class AddonModAssignSubmissionListPage implements AfterViewInit, OnDestro
|
||||||
assign?: AddonModAssignAssign; // Assignment.
|
assign?: AddonModAssignAssign; // Assignment.
|
||||||
submissions: AddonModAssignSubmissionListManager; // List of submissions
|
submissions: AddonModAssignSubmissionListManager; // List of submissions
|
||||||
loaded = false; // Whether data has been loaded.
|
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.
|
groupId = 0; // Group ID to show.
|
||||||
courseId!: number; // Course ID the assignment belongs to.
|
courseId!: number; // Course ID the assignment belongs to.
|
||||||
moduleId!: number; // Module ID the submission belongs to.
|
moduleId!: number; // Module ID the submission belongs to.
|
||||||
|
|
|
@ -37,7 +37,7 @@ export class AddonModAssignSubmissionReviewPage implements OnInit, CanLeave {
|
||||||
title = ''; // Title to display.
|
title = ''; // Title to display.
|
||||||
moduleId!: number; // Module ID the submission belongs to.
|
moduleId!: number; // Module ID the submission belongs to.
|
||||||
courseId!: number; // Course ID the assignment 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).
|
blindId?: number; // Blinded user ID (if it's blinded).
|
||||||
loaded = false; // Whether data has been loaded.
|
loaded = false; // Whether data has been loaded.
|
||||||
canSaveGrades = false; // Whether the user can save grades.
|
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.
|
// Override offline grade and outcomes based on the gradebook data.
|
||||||
grades.forEach((grade: CoreGradesFormattedItem | CoreGradesFormattedRow) => {
|
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 (!grade.outcomeid && !grade.scaleid) {
|
||||||
if (gradeInfo && gradeInfo.scale) {
|
if (gradeInfo && gradeInfo.scale) {
|
||||||
offlineData.grade = this.getSelectedScaleId(gradeInfo.scale, grade.grade || '');
|
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 SUBMITTED_FOR_GRADING_EVENT = 'addon_mod_assign_submitted_for_grading';
|
||||||
static readonly GRADED_EVENT = 'addon_mod_assign_graded';
|
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
|
* 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;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error && !CoreUtils.isWebServiceError(error)) {
|
if (error && !CoreUtils.isWebServiceError(error)) {
|
||||||
// Couldn't connect to server, store in offline.
|
// Couldn't connect to server, store in offline.
|
||||||
return storeOffline();
|
return storeOffline();
|
||||||
|
|
|
@ -79,7 +79,7 @@ export class AddonModAssignSubmissionFileComponent extends AddonModAssignSubmiss
|
||||||
// No offline data, get the online files.
|
// No offline data, get the online files.
|
||||||
this.files = AddonModAssign.getSubmissionPluginAttachments(this.plugin);
|
this.files = AddonModAssign.getSubmissionPluginAttachments(this.plugin);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
CoreFileSession.setFiles(this.component, this.assign.id, this.files);
|
CoreFileSession.setFiles(this.component, this.assign.id, this.files);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<nav>
|
<nav>
|
||||||
<ion-list>
|
<ion-list>
|
||||||
<ion-item class="ion-text-wrap" *ngFor="let chapter of chapters" (click)="loadChapter(chapter.id)"
|
<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">
|
[class.item-dimmed]="chapter.hidden">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<p [class.ion-padding-left]="addPadding && chapter.level == 1 ? true : null">
|
<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.
|
* Get the mod params necessary to open an activity.
|
||||||
*
|
*
|
||||||
* @param url The URL to treat.
|
* @param url The URL to treat.
|
||||||
* @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
* @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
|
||||||
* @return List of params to pass to navigateToModule / navigateToModuleByInstance.
|
* @return List of params to pass to navigateToModule / navigateToModuleByInstance.
|
||||||
*/
|
*/
|
||||||
getPageParams(url: string, params: Record<string, string>): Params {
|
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"
|
<core-context-menu-item *ngIf="loaded && isOnline" [priority]="700" [content]="'core.refresh' | translate"
|
||||||
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</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"
|
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon"
|
||||||
[closeOnClick]="false">
|
[closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
|
|
|
@ -201,7 +201,7 @@ export class AddonModChatChatPage implements OnInit, OnDestroy {
|
||||||
/**
|
/**
|
||||||
* Get the user fullname for a beep.
|
* Get the user fullname for a beep.
|
||||||
*
|
*
|
||||||
* @param id User Id before parsing.
|
* @param id User Id before parsing.
|
||||||
* @return User fullname.
|
* @return User fullname.
|
||||||
*/
|
*/
|
||||||
protected async getUserFullname(id: string): Promise<string> {
|
protected async getUserFullname(id: string): Promise<string> {
|
||||||
|
|
|
@ -120,7 +120,7 @@ export class AddonModChatSessionMessagesPage implements OnInit {
|
||||||
return user.fullname;
|
return user.fullname;
|
||||||
} catch {
|
} catch {
|
||||||
// Error getting profile.
|
// 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).
|
* 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.
|
* @param prevMessage Previous message object.
|
||||||
* @return True if messages are from diferent days, false othetwise.
|
* @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"
|
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
|
||||||
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</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">
|
[content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
|
<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> {
|
async invalidateOptions(choiceId: number, siteId?: string): Promise<void> {
|
||||||
const site = await CoreSites.getSite(siteId);
|
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> {
|
async invalidateResults(choiceId: number, siteId?: string): Promise<void> {
|
||||||
const site = await CoreSites.getSite(siteId);
|
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-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||||
</ion-button>
|
</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-icon name="fas-cog" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@
|
||||||
component="mod_data" [itemId]="entry.id" area="database_entry" [courseId]="database.course">
|
component="mod_data" [itemId]="entry.id" area="database_entry" [courseId]="database.course">
|
||||||
</core-comments>
|
</core-comments>
|
||||||
|
|
||||||
<span *ngIf="action == 'timeadded'">{{ entry.timecreated * 1000 | coreFormatDate }}</span>
|
<span *ngIf="action == 'timeadded'">{{ entry.timecreated * 1000 | coreFormatDate }}</span>
|
||||||
<span *ngIf="action == 'timemodified'">{{ entry.timemodified * 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">
|
<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
|
<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"
|
[content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon"
|
||||||
[closeOnClick]="false">
|
[closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</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"
|
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon"
|
||||||
[closeOnClick]="false">
|
[closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
|
|
|
@ -87,7 +87,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
|
||||||
|
|
||||||
hasNextPage = false;
|
hasNextPage = false;
|
||||||
entriesRendered = '';
|
entriesRendered = '';
|
||||||
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
|
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
|
||||||
|
|
||||||
jsData?: {
|
jsData?: {
|
||||||
fields: Record<number, AddonModDataField>;
|
fields: Record<number, AddonModDataField>;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<ion-toggle [(ngModel)]="search.searchingAdvanced"></ion-toggle>
|
<ion-toggle [(ngModel)]="search.searchingAdvanced"></ion-toggle>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<form (ngSubmit)="searchEntries($event)" [formGroup]="searchForm" #searchFormEl>
|
<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-item [hidden]="search.searchingAdvanced">
|
||||||
<ion-label></ion-label>
|
<ion-label></ion-label>
|
||||||
<ion-input type="text" placeholder="{{ 'addon.mod_data.search' | translate}}"
|
<ion-input type="text" placeholder="{{ 'addon.mod_data.search' | translate}}"
|
||||||
|
|
|
@ -49,7 +49,7 @@ export class AddonModDataSearchComponent implements OnInit {
|
||||||
|
|
||||||
advancedSearch = '';
|
advancedSearch = '';
|
||||||
advancedIndexed: CoreFormFields = {};
|
advancedIndexed: CoreFormFields = {};
|
||||||
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
|
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
|
||||||
|
|
||||||
searchForm: FormGroup;
|
searchForm: FormGroup;
|
||||||
jsData?: {
|
jsData?: {
|
||||||
|
|
|
@ -22,8 +22,6 @@
|
||||||
.addon-data-advanced-search {
|
.addon-data-advanced-search {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
// @todo check if needed
|
|
||||||
// @include safe-area-padding-horizontal(16px !important, 16px !important);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.addon-data-contents form,
|
.addon-data-contents form,
|
||||||
|
|
|
@ -17,8 +17,6 @@ $grid-column-paddings: (
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
// @todo check if needed
|
|
||||||
// @include safe-area-padding-horizontal(16px !important, 16px !important);
|
|
||||||
|
|
||||||
background-color: var(--ion-item-background);
|
background-color: var(--ion-item-background);
|
||||||
border-width: 1px 0;
|
border-width: 1px 0;
|
||||||
|
|
|
@ -93,7 +93,7 @@ export class AddonModDataFieldDateHandlerService implements AddonModDataFieldHan
|
||||||
{
|
{
|
||||||
fieldid: field.id,
|
fieldid: field.id,
|
||||||
subfield: 'year',
|
subfield: 'year',
|
||||||
value: date[0],
|
value: date[0],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldid: field.id,
|
fieldid: field.id,
|
||||||
|
|
|
@ -78,14 +78,14 @@ export class AddonModDataFieldFileHandlerService implements AddonModDataFieldHan
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
getFieldEditFiles(field: AddonModDataField): CoreFileEntry[] {
|
getFieldEditFiles(field: AddonModDataField): CoreFileEntry[] {
|
||||||
return CoreFileSession.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id);
|
return CoreFileSession.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
hasFieldDataChanged(field: AddonModDataField, inputData: CoreFormFields, originalFieldData: AddonModDataEntryField): boolean {
|
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) || [];
|
let originalFiles = (originalFieldData && originalFieldData.files) || [];
|
||||||
|
|
||||||
if (originalFiles.length) {
|
if (originalFiles.length) {
|
||||||
|
|
|
@ -146,7 +146,7 @@ export class AddonModDataFieldLatlongComponent extends AddonModDataFieldPluginCo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreDomUtils.showErrorModalDefault(error, 'Error getting location');
|
CoreDomUtils.showErrorModalDefault(error, 'Error getting location');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -133,7 +133,7 @@ export class AddonModDataFieldPictureComponent extends AddonModDataFieldPluginCo
|
||||||
}
|
}
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|
||||||
this.width = CoreDomUtils.formatPixelsSize(this.field.param1);
|
this.width = CoreDomUtils.formatPixelsSize(this.field.param1);
|
||||||
this.height = CoreDomUtils.formatPixelsSize(this.field.param2);
|
this.height = CoreDomUtils.formatPixelsSize(this.field.param2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ export class AddonModDataFieldPictureHandlerService implements AddonModDataField
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
getFieldEditFiles(field: AddonModDataField): CoreFileEntry[] {
|
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;
|
groupInfo?: CoreGroupInfo;
|
||||||
editFormRender = '';
|
editFormRender = '';
|
||||||
editForm: FormGroup;
|
editForm: FormGroup;
|
||||||
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
|
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
|
||||||
jsData?: {
|
jsData?: {
|
||||||
fields: Record<number, AddonModDataField>;
|
fields: Record<number, AddonModDataField>;
|
||||||
database?: AddonModDataData;
|
database?: AddonModDataData;
|
||||||
|
|
|
@ -77,7 +77,7 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy {
|
||||||
showComments = false;
|
showComments = false;
|
||||||
entryHtml = '';
|
entryHtml = '';
|
||||||
siteId: string;
|
siteId: string;
|
||||||
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
|
extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
|
||||||
jsData?: {
|
jsData?: {
|
||||||
fields: Record<number, AddonModDataField>;
|
fields: Record<number, AddonModDataField>;
|
||||||
entries: Record<number, AddonModDataEntry>;
|
entries: Record<number, AddonModDataEntry>;
|
||||||
|
|
|
@ -399,7 +399,7 @@ export class AddonModDataHelperProvider {
|
||||||
database: AddonModDataData,
|
database: AddonModDataData,
|
||||||
accessInfo: AddonModDataGetDataAccessInformationWSResponse,
|
accessInfo: AddonModDataGetDataAccessInformationWSResponse,
|
||||||
entry: AddonModDataEntry,
|
entry: AddonModDataEntry,
|
||||||
): Record<AddonModDataAction, boolean> {
|
): Record<AddonModDataAction, boolean> {
|
||||||
return {
|
return {
|
||||||
add: false, // Not directly used on entries.
|
add: false, // Not directly used on entries.
|
||||||
more: true,
|
more: true,
|
||||||
|
@ -719,7 +719,7 @@ export class AddonModDataHelperProvider {
|
||||||
// Ignore errors.
|
// 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);
|
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.
|
updated: boolean; // Whether some data was sent to the server or offline data was updated.
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AddonModDataAutoSyncData = {
|
export type AddonModDataAutoSyncData = {
|
||||||
dataId: number;
|
dataId: number;
|
||||||
warnings: string[];
|
warnings: string[];
|
||||||
entryId?: number;
|
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 dataId Data ID.
|
||||||
* @param options Other options.
|
* @param options Other options.
|
||||||
|
@ -1304,7 +1304,7 @@ type AddonModDataDeleteEntryWSParams = {
|
||||||
*/
|
*/
|
||||||
type AddonModDataUpdateEntryWSParams = {
|
type AddonModDataUpdateEntryWSParams = {
|
||||||
entryid: number; // The entry record id.
|
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"
|
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
|
||||||
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</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">
|
[content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
|
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2 *ngIf="item.name" [core-mark-required]="item.required">
|
<h2 *ngIf="item.name" [core-mark-required]="item.required">
|
||||||
<span *ngIf="feedback!.autonumbering && item.itemnumber">{{item.itemnumber}}. </span>
|
<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">
|
contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId">
|
||||||
</core-format-text>
|
</core-format-text>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
[required]="item.required" name="{{item.typ}}_{{item.id}}">
|
[required]="item.required" name="{{item.typ}}_{{item.id}}">
|
||||||
<ion-item *ngFor="let option of item.choices">
|
<ion-item *ngFor="let option of item.choices">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<core-format-text [component]="component" [componentId]="cmId"
|
<core-format-text [component]="component" [componentId]="cmId"
|
||||||
[text]="option.label" contextLevel="module" [contextInstanceId]="cmId"
|
[text]="option.label" contextLevel="module" [contextInstanceId]="cmId"
|
||||||
[wsNotFiltered]="true" [courseId]="courseId">
|
[wsNotFiltered]="true" [courseId]="courseId">
|
||||||
</core-format-text>
|
</core-format-text>
|
||||||
|
@ -146,7 +146,7 @@
|
||||||
{{ 'addon.mod_feedback.feedback_submitted_offline' | translate }}
|
{{ 'addon.mod_feedback.feedback_submitted_offline' | translate }}
|
||||||
</p>
|
</p>
|
||||||
<p *ngIf="completionPageContents">
|
<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">
|
contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId">
|
||||||
</core-format-text>
|
</core-format-text>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<core-loading [hideUntil]="loaded">
|
<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-item class="ion-text-wrap" *ngIf="groupInfo && (groupInfo.separateGroups || groupInfo.visibleGroups)">
|
||||||
<ion-label id="addon-feedback-groupslabel">
|
<ion-label id="addon-feedback-groupslabel">
|
||||||
<ng-container *ngIf="groupInfo.separateGroups">{{'core.groupsseparate' | translate }}</ng-container>
|
<ng-container *ngIf="groupInfo.separateGroups">{{'core.groupsseparate' | translate }}</ng-container>
|
||||||
|
|
|
@ -117,7 +117,7 @@ export class AddonModFeedbackHelperProvider {
|
||||||
if (itemData.typ == 'multichoice' || itemData.typ == 'multichoicerated') {
|
if (itemData.typ == 'multichoice' || itemData.typ == 'multichoicerated') {
|
||||||
value = itemData.value || 0;
|
value = itemData.value || 0;
|
||||||
} else if (this.isNumericItem(itemData)) {
|
} else if (this.isNumericItem(itemData)) {
|
||||||
value = itemData.value || itemData.value == 0 ? itemData.value : '';
|
value = itemData.value || itemData.value == 0 ? itemData.value : '';
|
||||||
|
|
||||||
if (value != '') {
|
if (value != '') {
|
||||||
if ((itemData.rangefrom != '' && value < itemData.rangefrom) ||
|
if ((itemData.rangefrom != '' && value < itemData.rangefrom) ||
|
||||||
|
@ -126,7 +126,7 @@ export class AddonModFeedbackHelperProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
value = itemData.value || itemData.value == 0 ? itemData.value : '';
|
value = itemData.value || itemData.value == 0 ? itemData.value : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
answered = !!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 feedbackId Feedback ID.
|
||||||
* @param options Other options.
|
* @param options Other options.
|
||||||
|
|
|
@ -255,7 +255,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
|
||||||
componentProps: {
|
componentProps: {
|
||||||
post: this.post,
|
post: this.post,
|
||||||
component: this.component,
|
component: this.component,
|
||||||
componentId: this.componentId,
|
componentId: this.componentId,
|
||||||
forum: this.forum,
|
forum: this.forum,
|
||||||
},
|
},
|
||||||
backdropDismiss: false,
|
backdropDismiss: false,
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<ion-list id="addon-mod-forum-sort-selector" role="listbox" aria-labelledby="addon-mod-forum-sort-order-label">
|
<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">
|
<ng-container *ngFor="let sortOrder of sortOrders">
|
||||||
<ion-item class="ion-text-wrap" detail="false" role="combobox"
|
<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">
|
(click)="selectSortOrder(sortOrder)" button aria-haspopup="dialog">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ sortOrder.label | translate }}</h2>
|
<h2>{{ sortOrder.label | translate }}</h2>
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ion-card>
|
</ion-card>
|
||||||
|
|
||||||
<div *ngIf="startingPost" class="ion-margin-bottom">
|
<div *ngIf="startingPost" class="ion-margin-bottom">
|
||||||
<addon-mod-forum-post
|
<addon-mod-forum-post
|
||||||
[post]="startingPost" [discussion]="discussion" [courseId]="courseId" [highlight]="true"
|
[post]="startingPost" [discussion]="discussion" [courseId]="courseId" [highlight]="true"
|
||||||
[discussionId]="discussionId" [component]="component" [componentId]="cmId"
|
[discussionId]="discussionId" [component]="component" [componentId]="cmId"
|
||||||
|
|
|
@ -531,9 +531,9 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
/**
|
/**
|
||||||
* Convenience function to load discussion.
|
* Convenience function to load discussion.
|
||||||
*
|
*
|
||||||
* @param forumId Forum ID.
|
* @param forumId Forum ID.
|
||||||
* @param cmId Forum cmid.
|
* @param cmId Forum cmid.
|
||||||
* @param discussionId Discussion ID.
|
* @param discussionId Discussion ID.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected async loadDiscussion(forumId: number, cmId: number, discussionId: number): Promise<void> {
|
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> {
|
async add(): Promise<void> {
|
||||||
const forumName = this.forum.name;
|
const forumName = this.forum.name;
|
||||||
const subject = this.newDiscussion.subject;
|
const subject = this.newDiscussion.subject;
|
||||||
let message = this.newDiscussion.message || '';
|
let message = this.newDiscussion.message || '';
|
||||||
const pin = this.newDiscussion.pin;
|
const pin = this.newDiscussion.pin;
|
||||||
const attachments = this.newDiscussion.files;
|
const attachments = this.newDiscussion.files;
|
||||||
const discTimecreated = this.timeCreated || Date.now();
|
const discTimecreated = this.timeCreated || Date.now();
|
||||||
|
|
|
@ -49,8 +49,6 @@ declare module '@singletons/events' {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service that provides some features for forums.
|
* Service that provides some features for forums.
|
||||||
*
|
|
||||||
* @todo Add all content.
|
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModForumProvider {
|
export class AddonModForumProvider {
|
||||||
|
|
|
@ -145,7 +145,7 @@ export class AddonModForumModuleHandlerService implements CoreCourseModuleHandle
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.extraBadge = Translate.instant('core.loading');
|
data.extraBadge = Translate.instant('core.loading');
|
||||||
data.extraBadgeColor = 'light';
|
data.extraBadgeColor = 'light';
|
||||||
|
|
||||||
await CoreUtils.ignoreErrors(AddonModForum.invalidateForumData(courseId));
|
await CoreUtils.ignoreErrors(AddonModForum.invalidateForumData(courseId));
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<nav>
|
<nav>
|
||||||
<ion-list>
|
<ion-list>
|
||||||
<ion-item *ngFor="let item of items" (click)="loadItem(item.href)"
|
<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">
|
<ion-label [class.core-bold]="!item.href">
|
||||||
<span class="ion-padding-left" *ngFor="let i of getNumberForPadding(item.level)"></span>{{item.title}}
|
<span class="ion-padding-left" *ngFor="let i of getNumberForPadding(item.level)"></span>{{item.title}}
|
||||||
</ion-label>
|
</ion-label>
|
||||||
|
|
|
@ -144,7 +144,7 @@ export class AddonModImscpProvider {
|
||||||
* @return Cache key.
|
* @return Cache key.
|
||||||
*/
|
*/
|
||||||
protected getImscpDataCacheKey(courseId: number): string {
|
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"
|
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
|
||||||
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</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">
|
[content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
|
<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!];
|
this.preventReasons = [preventReason!];
|
||||||
lessonReady = false;
|
lessonReady = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Lesson cannot be started.
|
// Lesson cannot be started.
|
||||||
this.preventReasons = [preventReason!];
|
this.preventReasons = [preventReason!];
|
||||||
lessonReady = false;
|
lessonReady = false;
|
||||||
|
|
|
@ -884,7 +884,7 @@ export class AddonModLessonProvider {
|
||||||
// Answer found.
|
// Answer found.
|
||||||
result.correctanswer = this.isAnswerCorrect(lesson, pageData.page!.id, answer, pageIndex);
|
result.correctanswer = this.isAnswerCorrect(lesson, pageData.page!.id, answer, pageIndex);
|
||||||
result.newpageid = answer.jumpto || 0;
|
result.newpageid = answer.jumpto || 0;
|
||||||
result.response = answer.response || '';
|
result.response = answer.response || '';
|
||||||
result.studentanswer = result.userresponse = answer.answer || '';
|
result.studentanswer = result.userresponse = answer.answer || '';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3195,7 +3195,7 @@ export class AddonModLessonProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
let nAttempts: number | undefined;
|
let nAttempts: number | undefined;
|
||||||
result.attemptsremaining = 0;
|
result.attemptsremaining = 0;
|
||||||
result.maxattemptsreached = false;
|
result.maxattemptsreached = false;
|
||||||
|
|
||||||
if (result.noanswer) {
|
if (result.noanswer) {
|
||||||
|
@ -3902,7 +3902,7 @@ export type AddonModLessonGetPagesWSResponse = {
|
||||||
*/
|
*/
|
||||||
export type AddonModLessonGetPagesPageWSData = {
|
export type AddonModLessonGetPagesPageWSData = {
|
||||||
page: AddonModLessonPageWSData; // Page fields.
|
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.
|
jumps: number[]; // List of possible page jumps.
|
||||||
filescount: number; // The total number of files attached to the page.
|
filescount: number; // The total number of files attached to the page.
|
||||||
filessizetotal: number; // The total size of the files.
|
filessizetotal: number; // The total size of the files.
|
||||||
|
|
|
@ -119,7 +119,7 @@ export class AddonModLtiModuleHandlerService implements CoreCourseModuleHandler
|
||||||
const siteId = CoreSites.getCurrentSiteId();
|
const siteId = CoreSites.getCurrentSiteId();
|
||||||
|
|
||||||
try {
|
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.
|
// Get the internal URL.
|
||||||
const url = await CoreFilepool.getSrcByUrl(siteId, icon, AddonModLtiProvider.COMPONENT, module.id);
|
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"
|
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
|
||||||
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</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">
|
[content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
|
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
|
||||||
|
@ -61,51 +61,62 @@
|
||||||
<!-- List of user attempts. -->
|
<!-- List of user attempts. -->
|
||||||
<ion-card class="addon-mod_quiz-table" *ngIf="quiz && attempts.length">
|
<ion-card class="addon-mod_quiz-table" *ngIf="quiz && attempts.length">
|
||||||
<ion-card-header class="ion-text-wrap">
|
<ion-card-header class="ion-text-wrap">
|
||||||
<ion-card-header>
|
<ion-card-title>{{ 'addon.mod_quiz.summaryofattempts' | translate }}</ion-card-title>
|
||||||
<ion-card-title>{{ 'addon.mod_quiz.summaryofattempts' | translate }}</ion-card-title>
|
|
||||||
</ion-card-header>
|
|
||||||
</ion-card-header>
|
</ion-card-header>
|
||||||
<ion-card-content>
|
<ion-card-content role="table">
|
||||||
<!-- "Header" of the table -->
|
<!-- "Header" of the table -->
|
||||||
<ion-item class="ion-text-wrap addon-mod_quiz-table-header" detail="true">
|
<ion-item class="ion-text-wrap addon-mod_quiz-table-header">
|
||||||
<ion-label>
|
<ion-label role="rowgroup">
|
||||||
<ion-row class="ion-align-items-center">
|
<ion-row class="ion-align-items-center" role="row">
|
||||||
<ion-col class="ion-text-center ion-hide-md-down" *ngIf="quiz.showAttemptColumn">
|
<ion-col class="ion-text-center" *ngIf="quiz.showAttemptColumn" role="columnheader">
|
||||||
<strong>{{ 'addon.mod_quiz.attemptnumber' | translate }}</strong>
|
<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>
|
||||||
<ion-col class="ion-text-center ion-hide-md-up" *ngIf="quiz.showAttemptColumn"><strong>#</strong></ion-col>
|
<ion-col size="7" role="columnheader">
|
||||||
<ion-col size="7"><strong>{{ 'addon.mod_quiz.attemptstate' | translate }}</strong></ion-col>
|
<strong>{{ 'addon.mod_quiz.attemptstate' | translate }}</strong>
|
||||||
<ion-col class="ion-text-center ion-hide-md-down" *ngIf="quiz.showMarkColumn">
|
</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>
|
<strong>{{ 'addon.mod_quiz.marks' | translate }} / {{ quiz.sumGradesFormatted }}</strong>
|
||||||
</ion-col>
|
</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>
|
<strong>{{ 'addon.mod_quiz.grade' | translate }} / {{ quiz.gradeFormatted }}</strong>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<!-- List of attempts. -->
|
<div role="rowgroup">
|
||||||
<ion-item class="ion-text-wrap" *ngFor="let attempt of attempts" button detail="true"
|
<!-- List of attempts. -->
|
||||||
[ngClass]='{"addon-mod_quiz-highlighted": attempt.highlightGrade}'
|
<ion-item
|
||||||
[attr.aria-label]="'core.seemoredetail' | translate" (click)="viewAttempt(attempt.id)">
|
button
|
||||||
<ion-label>
|
detail="true"
|
||||||
<ion-row class="ion-align-items-center">
|
*ngFor="let attempt of attempts"
|
||||||
<ion-col class="ion-text-center" *ngIf="quiz.showAttemptColumn && attempt.preview">
|
class="ion-text-wrap"
|
||||||
{{ 'addon.mod_quiz.preview' | translate }}
|
[ngClass]='{"addon-mod_quiz-highlighted": attempt.highlightGrade}'
|
||||||
</ion-col>
|
[attr.aria-label]="'core.seemoredetail' | translate"
|
||||||
<ion-col class="ion-text-center" *ngIf="quiz.showAttemptColumn && !attempt.preview">
|
(click)="viewAttempt(attempt.id)"
|
||||||
{{ attempt.attempt }}
|
>
|
||||||
</ion-col>
|
<ion-label>
|
||||||
<ion-col size="7">
|
<ion-row class="ion-align-items-center" role="row">
|
||||||
<p *ngFor="let sentence of attempt.readableState">{{ sentence }}</p>
|
<ion-col class="ion-text-center" *ngIf="quiz.showAttemptColumn && attempt.preview" role="cell">
|
||||||
</ion-col>
|
{{ 'addon.mod_quiz.preview' | translate }}
|
||||||
<ion-col class="ion-text-center ion-hide-md-down" *ngIf="quiz.showMarkColumn">
|
</ion-col>
|
||||||
<p>{{ attempt.readableMark }}</p>
|
<ion-col class="ion-text-center" *ngIf="quiz.showAttemptColumn && !attempt.preview" role="cell">
|
||||||
</ion-col>
|
{{ attempt.attempt }}
|
||||||
<ion-col class="ion-text-center" *ngIf="quiz.showGradeColumn"><p>{{ attempt.readableGrade }}</p></ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
<ion-col size="7" role="cell">
|
||||||
</ion-label>
|
<p *ngFor="let sentence of attempt.readableState">{{ sentence }}</p>
|
||||||
</ion-item>
|
</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-content>
|
||||||
</ion-card>
|
</ion-card>
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
<ion-card *ngIf="attempt">
|
<ion-card *ngIf="attempt">
|
||||||
<ion-card-header class="ion-text-wrap">
|
<ion-card-header class="ion-text-wrap">
|
||||||
<ion-card-title>
|
<ion-card-title>
|
||||||
<span *ngIf="attempt.preview">{{ 'addon.mod_quiz.reviewofpreview' | translate }}</span>
|
<ng-container *ngIf="attempt.preview">{{ 'addon.mod_quiz.reviewofpreview' | translate }}</ng-container>
|
||||||
<span *ngIf="!attempt.preview">{{ 'addon.mod_quiz.reviewofattempt' | translate:{$a: attempt.attempt} }}</span>
|
<ng-container *ngIf="!attempt.preview">{{ 'addon.mod_quiz.reviewofattempt' | translate:{$a: attempt.attempt} }}</ng-container>
|
||||||
</ion-card-title>
|
</ion-card-title>
|
||||||
</ion-card-header>
|
</ion-card-header>
|
||||||
<ion-list lines="none">
|
<ion-list lines="none">
|
||||||
|
|
|
@ -176,7 +176,7 @@ export class AddonModQuizHelperProvider {
|
||||||
throw new CoreCanceledError();
|
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.
|
timefinish?: number; // Time when the attempt was submitted. 0 if the attempt has not been submitted yet.
|
||||||
timemodified?: number; // Last modified time.
|
timemodified?: number; // Last modified time.
|
||||||
timemodifiedoffline?: number; // Last modified time via webservices.
|
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.
|
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"
|
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
|
||||||
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</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">
|
[content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
|
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
<ng-container *ngFor="let sco of toc">
|
<ng-container *ngFor="let sco of toc">
|
||||||
<ion-item *ngIf="sco.isvisible" class="ion-text-wrap" [detail]="sco.prereq && sco.launch"
|
<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"
|
[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">
|
[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 *ngIf="sco.icon" [name]="sco.icon.icon" [attr.aria-label]="sco.icon.description" slot="start">
|
||||||
</ion-icon>
|
</ion-icon>
|
||||||
|
|
|
@ -893,7 +893,7 @@ export class AddonModScormProvider {
|
||||||
|
|
||||||
const data = await this.getScormUserData(scormId, attempt, userDataOptions);
|
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.
|
// First populate trackDataBySCO to index by SCO identifier.
|
||||||
// We want the full list first because it's needed by evalPrerequisites.
|
// 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"
|
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
|
||||||
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</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)"
|
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)"
|
||||||
[iconAction]="syncIcon" [closeOnClick]="false">
|
[iconAction]="syncIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<ion-label><h2>{{ letter.label }}</h2></ion-label>
|
<ion-label><h2>{{ letter.label }}</h2></ion-label>
|
||||||
</ion-item-divider>
|
</ion-item-divider>
|
||||||
<ion-item class="ion-text-wrap" *ngFor="let page of letter.pages" (click)="goToPage(page)"
|
<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-icon name="fas-home" slot="start" *ngIf="page.firstpage" aria-hidden="true"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<core-format-text [text]="page.title" contextLevel="module" [contextInstanceId]="moduleId"
|
<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)"
|
<ion-item class="ion-text-wrap" *ngFor="let subwiki of group.subwikis" (click)="openSubwiki(subwiki)"
|
||||||
[attr.disabled]="!subwiki.canedit && subwiki.id <= 0"
|
[attr.disabled]="!subwiki.canedit && subwiki.id <= 0"
|
||||||
[button]="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-label>{{ subwiki.name }}</ion-label>
|
||||||
<ion-icon *ngIf="isSubwikiSelected(subwiki)" name="fas-check" slot="end" aria-hidden="true"></ion-icon>
|
<ion-icon *ngIf="isSubwikiSelected(subwiki)" name="fas-check" slot="end" aria-hidden="true"></ion-icon>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
|
@ -115,7 +115,7 @@ export class AddonModWorkshopAssessmentStrategyAccumulativeHandlerService implem
|
||||||
currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
|
currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
|
||||||
form: AddonModWorkshopGetAssessmentFormDefinitionData,
|
form: AddonModWorkshopGetAssessmentFormDefinitionData,
|
||||||
): Promise<CoreFormFields> {
|
): Promise<CoreFormFields> {
|
||||||
const data: CoreFormFields = {};
|
const data: CoreFormFields = {};
|
||||||
const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
|
const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
|
||||||
let hasErrors = false;
|
let hasErrors = false;
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ export class AddonModWorkshopAssessmentStrategyAccumulativeHandlerService implem
|
||||||
|
|
||||||
data['gradeid__idx_' + idx] = parseInt(form.current[idx].gradeid, 10) || 0;
|
data['gradeid__idx_' + idx] = parseInt(form.current[idx].gradeid, 10) || 0;
|
||||||
data['dimensionid__idx_' + idx] = parseInt(field.dimensionid, 10);
|
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[],
|
currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
|
||||||
form: AddonModWorkshopGetAssessmentFormDefinitionData,
|
form: AddonModWorkshopGetAssessmentFormDefinitionData,
|
||||||
): Promise<CoreFormFields> {
|
): Promise<CoreFormFields> {
|
||||||
const data: CoreFormFields = {};
|
const data: CoreFormFields = {};
|
||||||
const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
|
const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
|
||||||
let hasErrors = false;
|
let hasErrors = false;
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ export class AddonModWorkshopAssessmentStrategyNumErrorsHandlerService implement
|
||||||
originalValues[n] = {};
|
originalValues[n] = {};
|
||||||
originalValues[n].peercomment = form.current[n].peercomment || '';
|
originalValues[n].peercomment = form.current[n].peercomment || '';
|
||||||
originalValues[n].number = field.number; // eslint-disable-line id-blacklist
|
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;
|
return originalValues;
|
||||||
|
@ -98,7 +98,7 @@ export class AddonModWorkshopAssessmentStrategyNumErrorsHandlerService implement
|
||||||
currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
|
currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
|
||||||
form: AddonModWorkshopGetAssessmentFormDefinitionData,
|
form: AddonModWorkshopGetAssessmentFormDefinitionData,
|
||||||
): Promise<CoreFormFields> {
|
): Promise<CoreFormFields> {
|
||||||
const data: CoreFormFields = {};
|
const data: CoreFormFields = {};
|
||||||
const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
|
const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
|
||||||
let hasErrors = false;
|
let hasErrors = false;
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ export class AddonModWorkshopAssessmentStrategyNumErrorsHandlerService implement
|
||||||
|
|
||||||
data['gradeid__idx_' + idx] = parseInt(form.current[idx].gradeid, 10) || 0;
|
data['gradeid__idx_' + idx] = parseInt(form.current[idx].gradeid, 10) || 0;
|
||||||
data['dimensionid__idx_' + idx] = parseInt(field.dimensionid, 10);
|
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[],
|
currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
|
||||||
form: AddonModWorkshopGetAssessmentFormDefinitionData,
|
form: AddonModWorkshopGetAssessmentFormDefinitionData,
|
||||||
): Promise<CoreFormFields> {
|
): Promise<CoreFormFields> {
|
||||||
const data: CoreFormFields = {};
|
const data: CoreFormFields = {};
|
||||||
const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
|
const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
|
||||||
let hasErrors = false;
|
let hasErrors = false;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
|
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
|
||||||
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</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"
|
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon"
|
||||||
[closeOnClick]="false">
|
[closeOnClick]="false">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<ion-list>
|
<ion-list>
|
||||||
<ng-container *ngFor="let phase of phases">
|
<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>
|
<ion-label>
|
||||||
<h2>{{ phase.title }}</h2>
|
<h2>{{ phase.title }}</h2>
|
||||||
<p class="ion-text-wrap" *ngIf="workshopPhase == phase.code">
|
<p class="ion-text-wrap" *ngIf="workshopPhase == phase.code">
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
</span>
|
</span>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
<core-rich-text-editor [control]="editForm.controls['content']" name="content"
|
<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"
|
[componentId]="componentId" [autoSave]="true" contextLevel="module" [contextInstanceId]="module.id"
|
||||||
elementId="content_editor" [draftExtraParams]="editorExtraParams"></core-rich-text-editor>
|
elementId="content_editor" [draftExtraParams]="editorExtraParams"></core-rich-text-editor>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue