commit
62ce8a3536
|
@ -1,6 +1,6 @@
|
|||
<ion-item-divider>
|
||||
<h2>{{ 'addon.block_recentlyaccessedcourses.pluginname' | translate }}</h2>
|
||||
<div *ngIf="downloadEnabled && courses && courses.length > 1" class="core-button-spinner" item-end>
|
||||
<div *ngIf="downloadCoursesEnabled && downloadEnabled && courses && courses.length > 1" class="core-button-spinner" item-end>
|
||||
<button *ngIf="prefetchCoursesData.icon && prefetchCoursesData.icon != 'spinner'" ion-button icon-only clear color="dark" (click)="prefetchCourses()">
|
||||
<core-icon [name]="prefetchCoursesData.icon"></core-icon>
|
||||
</button>
|
||||
|
@ -13,7 +13,7 @@
|
|||
<!-- List of courses. -->
|
||||
<div class="core-horizontal-scroll">
|
||||
<ng-container *ngFor="let course of courses">
|
||||
<core-courses-course-progress [course]="course" class="core-recentlyaccessedcourses" [showDownload]="downloadEnabled"></core-courses-course-progress>
|
||||
<core-courses-course-progress [course]="course" class="core-recentlyaccessedcourses" [showDownload]="downloadCourseEnabled && downloadEnabled"></core-courses-course-progress>
|
||||
</ng-container>
|
||||
</div>
|
||||
</core-loading>
|
||||
|
|
|
@ -37,10 +37,13 @@ export class AddonBlockRecentlyAccessedCoursesComponent extends CoreBlockBaseCom
|
|||
icon: '',
|
||||
badge: ''
|
||||
};
|
||||
downloadCourseEnabled: boolean;
|
||||
downloadCoursesEnabled: boolean;
|
||||
|
||||
protected prefetchIconsInitialized = false;
|
||||
protected isDestroyed;
|
||||
protected coursesObserver;
|
||||
protected updateSiteObserver;
|
||||
protected courseIds = [];
|
||||
protected fetchContentDefaultError = 'Error getting recent courses data.';
|
||||
|
||||
|
@ -58,6 +61,17 @@ export class AddonBlockRecentlyAccessedCoursesComponent extends CoreBlockBaseCom
|
|||
*/
|
||||
ngOnInit(): void {
|
||||
|
||||
// Refresh the enabled flags if enabled.
|
||||
this.downloadCourseEnabled = !this.coursesProvider.isDownloadCourseDisabledInSite();
|
||||
this.downloadCoursesEnabled = !this.coursesProvider.isDownloadCoursesDisabledInSite();
|
||||
|
||||
// Refresh the enabled flags if site is updated.
|
||||
this.updateSiteObserver = this.eventsProvider.on(CoreEventsProvider.SITE_UPDATED, () => {
|
||||
this.downloadCourseEnabled = !this.coursesProvider.isDownloadCourseDisabledInSite();
|
||||
this.downloadCoursesEnabled = !this.coursesProvider.isDownloadCoursesDisabledInSite();
|
||||
|
||||
}, this.sitesProvider.getCurrentSiteId());
|
||||
|
||||
this.coursesObserver = this.eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, () => {
|
||||
this.refreshContent();
|
||||
}, this.sitesProvider.getCurrentSiteId());
|
||||
|
@ -154,5 +168,6 @@ export class AddonBlockRecentlyAccessedCoursesComponent extends CoreBlockBaseCom
|
|||
ngOnDestroy(): void {
|
||||
this.isDestroyed = true;
|
||||
this.coursesObserver && this.coursesObserver.off();
|
||||
this.updateSiteObserver && this.updateSiteObserver.off();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<ion-item-divider>
|
||||
<h2>{{ 'addon.block_starredcourses.pluginname' | translate }}</h2>
|
||||
<div *ngIf="downloadEnabled && courses && courses.length > 1" class="core-button-spinner" item-end>
|
||||
<div *ngIf="downloadCoursesEnabled && downloadEnabled && courses && courses.length > 1" class="core-button-spinner" item-end>
|
||||
<button *ngIf="prefetchCoursesData.icon && prefetchCoursesData.icon != 'spinner'" ion-button icon-only clear color="dark" (click)="prefetchCourses()">
|
||||
<core-icon [name]="prefetchCoursesData.icon"></core-icon>
|
||||
</button>
|
||||
|
@ -13,7 +13,7 @@
|
|||
<!-- List of courses. -->
|
||||
<div class="core-horizontal-scroll">
|
||||
<ng-container *ngFor="let course of courses">
|
||||
<core-courses-course-progress [course]="course" class="core-block_starredcourses" [showDownload]="downloadEnabled"></core-courses-course-progress>
|
||||
<core-courses-course-progress [course]="course" class="core-block_starredcourses" [showDownload]="downloadCourseEnabled && downloadEnabled"></core-courses-course-progress>
|
||||
</ng-container>
|
||||
</div>
|
||||
</core-loading>
|
||||
|
|
|
@ -37,10 +37,13 @@ export class AddonBlockStarredCoursesComponent extends CoreBlockBaseComponent im
|
|||
icon: '',
|
||||
badge: ''
|
||||
};
|
||||
downloadCourseEnabled: boolean;
|
||||
downloadCoursesEnabled: boolean;
|
||||
|
||||
protected prefetchIconsInitialized = false;
|
||||
protected isDestroyed;
|
||||
protected coursesObserver;
|
||||
protected updateSiteObserver;
|
||||
protected courseIds = [];
|
||||
protected fetchContentDefaultError = 'Error getting starred courses data.';
|
||||
|
||||
|
@ -58,6 +61,17 @@ export class AddonBlockStarredCoursesComponent extends CoreBlockBaseComponent im
|
|||
*/
|
||||
ngOnInit(): void {
|
||||
|
||||
// Refresh the enabled flags if enabled.
|
||||
this.downloadCourseEnabled = !this.coursesProvider.isDownloadCourseDisabledInSite();
|
||||
this.downloadCoursesEnabled = !this.coursesProvider.isDownloadCoursesDisabledInSite();
|
||||
|
||||
// Refresh the enabled flags if site is updated.
|
||||
this.updateSiteObserver = this.eventsProvider.on(CoreEventsProvider.SITE_UPDATED, () => {
|
||||
this.downloadCourseEnabled = !this.coursesProvider.isDownloadCourseDisabledInSite();
|
||||
this.downloadCoursesEnabled = !this.coursesProvider.isDownloadCoursesDisabledInSite();
|
||||
|
||||
}, this.sitesProvider.getCurrentSiteId());
|
||||
|
||||
this.coursesObserver = this.eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, () => {
|
||||
this.refreshContent();
|
||||
}, this.sitesProvider.getCurrentSiteId());
|
||||
|
@ -154,5 +168,6 @@ export class AddonBlockStarredCoursesComponent extends CoreBlockBaseComponent im
|
|||
ngOnDestroy(): void {
|
||||
this.isDestroyed = true;
|
||||
this.coursesObserver && this.coursesObserver.off();
|
||||
this.updateSiteObserver && this.updateSiteObserver.off();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,3 +14,32 @@ ion-app.app-root addon-block-timeline-events {
|
|||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
ion-app.app-root core-courses-course-progress addon-block-timeline-events {
|
||||
@include media-breakpoint-up(md) {
|
||||
.hidden-tablet {
|
||||
display: block !important;
|
||||
opacity: 1 !important;
|
||||
&.button[disabled] {
|
||||
opacity: .4 !important;
|
||||
}
|
||||
}
|
||||
.hidden-phone {
|
||||
display: none !important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
}
|
||||
@include media-breakpoint-up(lg) {
|
||||
.hidden-tablet {
|
||||
display: none !important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
.hidden-phone {
|
||||
display: block !important;
|
||||
opacity: 1 !important;
|
||||
&.button[disabled] {
|
||||
opacity: .4 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import { CoreSyncBaseProvider } from '@classes/base-sync';
|
|||
import { AddonModAssignProvider, AddonModAssignAssign } from './assign';
|
||||
import { AddonModAssignOfflineProvider } from './assign-offline';
|
||||
import { AddonModAssignSubmissionDelegate } from './submission-delegate';
|
||||
import { AddonModAssignFeedbackDelegate } from './feedback-delegate';
|
||||
|
||||
/**
|
||||
* Data returned by an assign sync.
|
||||
|
@ -55,13 +56,22 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider {
|
|||
|
||||
protected componentTranslate: string;
|
||||
|
||||
constructor(loggerProvider: CoreLoggerProvider, sitesProvider: CoreSitesProvider, appProvider: CoreAppProvider,
|
||||
syncProvider: CoreSyncProvider, textUtils: CoreTextUtilsProvider, translate: TranslateService,
|
||||
private courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider,
|
||||
private assignProvider: AddonModAssignProvider, private assignOfflineProvider: AddonModAssignOfflineProvider,
|
||||
private utils: CoreUtilsProvider, private submissionDelegate: AddonModAssignSubmissionDelegate,
|
||||
private gradesHelper: CoreGradesHelperProvider, timeUtils: CoreTimeUtilsProvider,
|
||||
private logHelper: CoreCourseLogHelperProvider) {
|
||||
constructor(loggerProvider: CoreLoggerProvider,
|
||||
sitesProvider: CoreSitesProvider,
|
||||
appProvider: CoreAppProvider,
|
||||
syncProvider: CoreSyncProvider,
|
||||
textUtils: CoreTextUtilsProvider,
|
||||
translate: TranslateService,
|
||||
timeUtils: CoreTimeUtilsProvider,
|
||||
protected courseProvider: CoreCourseProvider,
|
||||
protected eventsProvider: CoreEventsProvider,
|
||||
protected assignProvider: AddonModAssignProvider,
|
||||
protected assignOfflineProvider: AddonModAssignOfflineProvider,
|
||||
protected utils: CoreUtilsProvider,
|
||||
protected submissionDelegate: AddonModAssignSubmissionDelegate,
|
||||
protected feedbackDelegate: AddonModAssignFeedbackDelegate,
|
||||
protected gradesHelper: CoreGradesHelperProvider,
|
||||
protected logHelper: CoreCourseLogHelperProvider) {
|
||||
|
||||
super('AddonModAssignSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
|
||||
timeUtils);
|
||||
|
@ -403,9 +413,19 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider {
|
|||
return this.assignProvider.submitGradingFormOnline(assign.id, userId, offlineData.grade, offlineData.attemptnumber,
|
||||
offlineData.addattempt, offlineData.workflowstate, offlineData.applytoall, offlineData.outcomes,
|
||||
offlineData.plugindata, siteId).then(() => {
|
||||
// Grades sent.
|
||||
// Discard grades drafts.
|
||||
const promises = [];
|
||||
if (status.feedback && status.feedback.plugins) {
|
||||
status.feedback.plugins.forEach((plugin) => {
|
||||
promises.push(this.feedbackDelegate.discardPluginFeedbackData(assign.id, userId, plugin, siteId));
|
||||
});
|
||||
}
|
||||
|
||||
// Grades sent, update cached data. No need to block the user for this.
|
||||
this.assignProvider.getSubmissionStatus(assign.id, userId, undefined, false, true, true, siteId);
|
||||
// Update cached data.
|
||||
promises.push(this.assignProvider.getSubmissionStatus(assign.id, userId, undefined, false, true, true, siteId));
|
||||
|
||||
return Promise.all(promises);
|
||||
}).catch((error) => {
|
||||
if (error && this.utils.isWebServiceError(error)) {
|
||||
// The WebService has thrown an error, this means it cannot be submitted. Discard the offline data.
|
||||
|
|
|
@ -286,6 +286,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
|
||||
let entriesHTML = this.dataHelper.getTemplate(this.data, 'listtemplateheader', this.fieldsArray);
|
||||
|
||||
console.error(entriesHTML);
|
||||
// Get first entry from the whole list.
|
||||
if (!this.search.searching || !this.firstEntry) {
|
||||
this.firstEntry = this.entries[0].id;
|
||||
|
@ -305,7 +306,8 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
});
|
||||
entriesHTML += this.dataHelper.getTemplate(this.data, 'listtemplatefooter', this.fieldsArray);
|
||||
|
||||
this.entriesRendered = entriesHTML;
|
||||
this.entriesRendered = this.domUtils.fixHtml(entriesHTML);
|
||||
console.error(entriesHTML);
|
||||
|
||||
// Pass the input data to the component.
|
||||
this.jsData = {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
white-space: normal;
|
||||
word-break: break-word;
|
||||
padding: $content-padding;
|
||||
@include safe-area-padding-horizontal($content-padding !important, $content-padding !important);
|
||||
background-color: $white;
|
||||
border-top-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
|
@ -31,6 +32,18 @@
|
|||
@extend .col;
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
// Do not let block elements to define widths or heights.
|
||||
address, article, aside, blockquote, canvas, dd, div, dl, dt, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6,
|
||||
header, hr, li, main, nav, noscript, ol, p, pre, section, table, tfoot, ul, video {
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
min-width: auto !important;
|
||||
min-height: auto !important;
|
||||
// Avoid having one entry over another.
|
||||
max-height: none !important;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
page-addon-mod-data-search,
|
||||
|
|
|
@ -599,8 +599,10 @@ export class AddonModDataHelperProvider {
|
|||
getTemplate(data: any, type: string, fields: any[]): string {
|
||||
let template = data[type] || this.getDefaultTemplate(type, fields);
|
||||
|
||||
// Try to fix syntax errors so the template can be parsed by Angular.
|
||||
template = this.domUtils.fixHtml(template);
|
||||
if (type != 'listtemplateheader' && type != 'listtemplatefooter') {
|
||||
// Try to fix syntax errors so the template can be parsed by Angular.
|
||||
template = this.domUtils.fixHtml(template);
|
||||
}
|
||||
|
||||
// Add core-link directive to links.
|
||||
template = template.replace(/<a ([^>]*href="[^>]*)>/ig, (match, attributes) => {
|
||||
|
|
|
@ -154,6 +154,7 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
|
|||
promises.push(this.workshopProvider.invalidateReviewerAssesmentsData(this.workshop.id));
|
||||
}
|
||||
promises.push(this.workshopProvider.invalidateGradesData(this.workshop.id));
|
||||
promises.push(this.workshopProvider.invalidateWorkshopWSData(this.workshop.id));
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-refresher [enabled]="loaded" (ionRefresh)="refreshAssessment($event)">
|
||||
<ion-refresher [enabled]="loaded" (ionRefresh)="refreshAssessment($event)" *ngIf="!evaluating">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
<core-loading [hideUntil]="loaded">
|
||||
|
|
|
@ -9,9 +9,6 @@
|
|||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-refresher [enabled]="loaded" (ionRefresh)="refreshSubmission($event)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
<core-loading [hideUntil]="loaded">
|
||||
<form ion-list [formGroup]="editForm" *ngIf="workshop">
|
||||
<ion-item text-wrap>
|
||||
|
|
|
@ -274,26 +274,6 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull to refresh.
|
||||
*
|
||||
* @param refresher Refresher.
|
||||
*/
|
||||
refreshSubmission(refresher: any): void {
|
||||
if (this.loaded) {
|
||||
const promises = [];
|
||||
|
||||
promises.push(this.workshopProvider.invalidateSubmissionData(this.workshopId, this.submission.id));
|
||||
promises.push(this.workshopProvider.invalidateSubmissionsData(this.workshopId));
|
||||
|
||||
Promise.all(promises).finally(() => {
|
||||
return this.fetchSubmissionData();
|
||||
}).finally(() => {
|
||||
refresher.complete();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the submission.
|
||||
*/
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-refresher [enabled]="loaded" (ionRefresh)="refreshSubmission($event)">
|
||||
<ion-refresher [enabled]="loaded" (ionRefresh)="refreshSubmission($event)" *ngIf="!((assessmentId && access.assessingallowed) || canAddFeedback)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
<core-loading [hideUntil]="loaded">
|
||||
|
|
|
@ -373,6 +373,10 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy {
|
|||
promises.push(this.workshopProvider.invalidateAssessmentData(this.workshopId, this.assessmentId));
|
||||
}
|
||||
|
||||
if (this.assessmentUserId) {
|
||||
promises.push(this.workshopProvider.invalidateReviewerAssesmentsData(this.workshopId, this.assessmentId));
|
||||
}
|
||||
|
||||
return Promise.all(promises).finally(() => {
|
||||
this.eventsProvider.trigger(AddonModWorkshopProvider.ASSESSMENT_INVALIDATED, this.siteId);
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ export class AddonModWorkshopHelperProvider {
|
|||
const task = this.getTask(tasks, taskCode);
|
||||
|
||||
if (task) {
|
||||
return task.completed;
|
||||
return !!task.completed;
|
||||
}
|
||||
|
||||
// Task not found, assume true.
|
||||
|
|
|
@ -33,9 +33,9 @@ export class AddonModWorkshopProvider {
|
|||
static PHASE_ASSESSMENT = 30;
|
||||
static PHASE_EVALUATION = 40;
|
||||
static PHASE_CLOSED = 50;
|
||||
static EXAMPLES_VOLUNTARY: 0;
|
||||
static EXAMPLES_BEFORE_SUBMISSION: 1;
|
||||
static EXAMPLES_BEFORE_ASSESSMENT: 2;
|
||||
static EXAMPLES_VOLUNTARY = 0;
|
||||
static EXAMPLES_BEFORE_SUBMISSION = 1;
|
||||
static EXAMPLES_BEFORE_ASSESSMENT = 2;
|
||||
static SUBMISSION_TYPE_DISABLED = 0;
|
||||
static SUBMISSION_TYPE_AVAILABLE = 1;
|
||||
static SUBMISSION_TYPE_REQUIRED = 2;
|
||||
|
|
|
@ -25,6 +25,7 @@ ion-app.app-root .ion-page {
|
|||
color: $core-dark-link-color;
|
||||
}
|
||||
|
||||
.core-tabs-bar,
|
||||
.core-tabs-bar *,
|
||||
.core-tabs-bar .tab-slide,
|
||||
.ion-page,
|
||||
|
|
|
@ -474,6 +474,7 @@ $core-dd-question-colors: $white, $blue-light, #DCDCDC, #D8BFD8, #87CEFA, #DAA52
|
|||
}
|
||||
|
||||
@mixin safe-area-position($top: null, $end: null, $bottom: null, $start: null) {
|
||||
@include position-horizontal($start, $end);
|
||||
@include safe-position-horizontal($start, $end);
|
||||
top: $top;
|
||||
bottom: $bottom;
|
||||
|
|
Loading…
Reference in New Issue