commit
e0a53d4a08
|
@ -19,12 +19,12 @@
|
||||||
<ion-input name="title" type="text" [placeholder]="'addon.mod_workshop.submissiontitle' | translate" formControlName="title"></ion-input>
|
<ion-input name="title" type="text" [placeholder]="'addon.mod_workshop.submissiontitle' | translate" formControlName="title"></ion-input>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
<ion-item>
|
<ion-item *ngIf="textAvailable">
|
||||||
<ion-label stacked>{{ 'addon.mod_workshop.submissioncontent' | translate }}</ion-label>
|
<ion-label stacked [core-mark-required]="textRequired">{{ 'addon.mod_workshop.submissioncontent' | translate }}</ion-label>
|
||||||
<core-rich-text-editor item-content [control]="editForm.controls['content']" formControlName="content" [placeholder]="'addon.mod_workshop.submissioncontent' | translate" name="content" [component]="component" [componentId]="componentId"></core-rich-text-editor>
|
<core-rich-text-editor item-content [control]="editForm.controls['content']" formControlName="content" [placeholder]="'addon.mod_workshop.submissioncontent' | translate" name="content" [component]="component" [componentId]="componentId"></core-rich-text-editor>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
<core-attachments *ngIf="workshop.nattachments > 0" [files]="submission.attachmentfiles" [maxSize]="workshop.maxbytes" [maxSubmissions]="workshop.nattachments" [component]="component" [componentId]="workshop.cmid" allowOffline="true" [acceptedTypes]="workshop.submissionfiletypes"></core-attachments>
|
<core-attachments *ngIf="fileAvailable" [files]="submission.attachmentfiles" [maxSize]="workshop.maxbytes" [maxSubmissions]="workshop.nattachments" [component]="component" [componentId]="workshop.cmid" allowOffline="true" [acceptedTypes]="workshop.submissionfiletypes" [required]="fileRequired"></core-attachments>
|
||||||
</form>
|
</form>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
|
@ -62,6 +62,10 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
|
||||||
protected siteId: string;
|
protected siteId: string;
|
||||||
protected workshop: any;
|
protected workshop: any;
|
||||||
protected isDestroyed = false;
|
protected isDestroyed = false;
|
||||||
|
protected textAvailable = false;
|
||||||
|
protected textRequired = false;
|
||||||
|
protected fileAvailable = false;
|
||||||
|
protected fileRequired = false;
|
||||||
|
|
||||||
constructor(navParams: NavParams, sitesProvider: CoreSitesProvider, protected fileUploaderProvider: CoreFileUploaderProvider,
|
constructor(navParams: NavParams, sitesProvider: CoreSitesProvider, protected fileUploaderProvider: CoreFileUploaderProvider,
|
||||||
protected workshopProvider: AddonModWorkshopProvider, protected workshopOffline: AddonModWorkshopOfflineProvider,
|
protected workshopProvider: AddonModWorkshopProvider, protected workshopOffline: AddonModWorkshopOfflineProvider,
|
||||||
|
@ -132,6 +136,12 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
|
||||||
protected fetchSubmissionData(): Promise<void> {
|
protected fetchSubmissionData(): Promise<void> {
|
||||||
return this.workshopProvider.getWorkshop(this.courseId, this.module.id).then((workshopData) => {
|
return this.workshopProvider.getWorkshop(this.courseId, this.module.id).then((workshopData) => {
|
||||||
this.workshop = workshopData;
|
this.workshop = workshopData;
|
||||||
|
this.textAvailable = (this.workshop.submissiontypetext != AddonModWorkshopProvider.SUBMISSION_TYPE_DISABLED);
|
||||||
|
this.textRequired = (this.workshop.submissiontypetext == AddonModWorkshopProvider.SUBMISSION_TYPE_REQUIRED);
|
||||||
|
this.fileAvailable = (this.workshop.submissiontypefile != AddonModWorkshopProvider.SUBMISSION_TYPE_DISABLED);
|
||||||
|
this.fileRequired = (this.workshop.submissiontypefile == AddonModWorkshopProvider.SUBMISSION_TYPE_REQUIRED);
|
||||||
|
|
||||||
|
this.editForm.controls.content.setValidators(this.textRequired ? Validators.required : null);
|
||||||
|
|
||||||
if (this.submissionId > 0) {
|
if (this.submissionId > 0) {
|
||||||
this.editing = true;
|
this.editing = true;
|
||||||
|
@ -220,8 +230,19 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
|
||||||
protected getInputData(): any {
|
protected getInputData(): any {
|
||||||
const submissionId = this.submission.id || 'newsub';
|
const submissionId = this.submission.id || 'newsub';
|
||||||
|
|
||||||
const values = this.editForm.value;
|
const values = {
|
||||||
values['attachmentfiles'] = this.fileSessionprovider.getFiles(this.component, this.workshopId + '_' + submissionId) || [];
|
title: this.editForm.value.title,
|
||||||
|
content: null,
|
||||||
|
attachmentfiles: []
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.textAvailable) {
|
||||||
|
values.content = this.editForm.value.content || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.fileAvailable) {
|
||||||
|
values.attachmentfiles = this.fileSessionprovider.getFiles(this.component, this.workshopId + '_' + submissionId) || [];
|
||||||
|
}
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
@ -242,13 +263,17 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.originalData.title != inputData.title || this.originalData.content != inputData.content) {
|
if (this.originalData.title != inputData.title || this.textAvailable && this.originalData.content != inputData.content) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.fileAvailable) {
|
||||||
return this.fileUploaderProvider.areFileListDifferent(inputData.attachmentfiles, this.originalData.attachmentfiles);
|
return this.fileUploaderProvider.areFileListDifferent(inputData.attachmentfiles, this.originalData.attachmentfiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pull to refresh.
|
* Pull to refresh.
|
||||||
*
|
*
|
||||||
|
@ -300,7 +325,10 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
return Promise.reject(null);
|
return Promise.reject(null);
|
||||||
}
|
}
|
||||||
if (!inputData.content) {
|
|
||||||
|
const noText = this.textUtils.htmlIsBlank(inputData.content);
|
||||||
|
const noFiles = !inputData.attachmentfiles.length;
|
||||||
|
if (this.textRequired && noText || this.fileRequired && noFiles || noText && noFiles) {
|
||||||
this.domUtils.showAlertTranslated('core.notice', 'addon.mod_workshop.submissionrequiredcontent');
|
this.domUtils.showAlertTranslated('core.notice', 'addon.mod_workshop.submissionrequiredcontent');
|
||||||
|
|
||||||
return Promise.reject(null);
|
return Promise.reject(null);
|
||||||
|
@ -313,7 +341,9 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
|
||||||
submissionId = this.submission.id;
|
submissionId = this.submission.id;
|
||||||
|
|
||||||
// Add some HTML to the message if needed.
|
// Add some HTML to the message if needed.
|
||||||
|
if (this.textAvailable) {
|
||||||
inputData.content = this.textUtils.formatHtmlLines(inputData.content);
|
inputData.content = this.textUtils.formatHtmlLines(inputData.content);
|
||||||
|
}
|
||||||
|
|
||||||
// Upload attachments first if any.
|
// Upload attachments first if any.
|
||||||
allowOffline = !inputData.attachmentfiles.length;
|
allowOffline = !inputData.attachmentfiles.length;
|
||||||
|
@ -327,6 +357,10 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
|
||||||
return this.workshopHelper.uploadOrStoreSubmissionFiles(this.workshopId, this.submission.id,
|
return this.workshopHelper.uploadOrStoreSubmissionFiles(this.workshopId, this.submission.id,
|
||||||
inputData.attachmentfiles, this.editing, saveOffline);
|
inputData.attachmentfiles, this.editing, saveOffline);
|
||||||
}).then((attachmentsId) => {
|
}).then((attachmentsId) => {
|
||||||
|
if (!saveOffline && !this.fileAvailable) {
|
||||||
|
attachmentsId = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.editing) {
|
if (this.editing) {
|
||||||
if (saveOffline) {
|
if (saveOffline) {
|
||||||
// Save submission in offline.
|
// Save submission in offline.
|
||||||
|
|
|
@ -318,6 +318,10 @@ export class AddonModWorkshopSyncProvider extends CoreSyncBaseProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileProm.then((attachmentsId) => {
|
return fileProm.then((attachmentsId) => {
|
||||||
|
if (workshop.submissiontypefile == AddonModWorkshopProvider.SUBMISSION_TYPE_DISABLED) {
|
||||||
|
attachmentsId = null;
|
||||||
|
}
|
||||||
|
|
||||||
// Perform the action.
|
// Perform the action.
|
||||||
switch (action.action) {
|
switch (action.action) {
|
||||||
case 'add':
|
case 'add':
|
||||||
|
|
|
@ -34,6 +34,9 @@ export class AddonModWorkshopProvider {
|
||||||
static EXAMPLES_VOLUNTARY: 0;
|
static EXAMPLES_VOLUNTARY: 0;
|
||||||
static EXAMPLES_BEFORE_SUBMISSION: 1;
|
static EXAMPLES_BEFORE_SUBMISSION: 1;
|
||||||
static EXAMPLES_BEFORE_ASSESSMENT: 2;
|
static EXAMPLES_BEFORE_ASSESSMENT: 2;
|
||||||
|
static SUBMISSION_TYPE_DISABLED = 0;
|
||||||
|
static SUBMISSION_TYPE_AVAILABLE = 1;
|
||||||
|
static SUBMISSION_TYPE_REQUIRED = 2;
|
||||||
|
|
||||||
static SUBMISSION_CHANGED = 'addon_mod_workshop_submission_changed';
|
static SUBMISSION_CHANGED = 'addon_mod_workshop_submission_changed';
|
||||||
static ASSESSMENT_SAVED = 'addon_mod_workshop_assessment_saved';
|
static ASSESSMENT_SAVED = 'addon_mod_workshop_assessment_saved';
|
||||||
|
@ -223,6 +226,19 @@ export class AddonModWorkshopProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(null);
|
return Promise.reject(null);
|
||||||
|
}).then((workshop) => {
|
||||||
|
// Set submission types for Moodle 3.5 and older.
|
||||||
|
if (typeof workshop.submissiontypetext == 'undefined') {
|
||||||
|
if (workshop.nattachments > 0) {
|
||||||
|
workshop.submissiontypetext = AddonModWorkshopProvider.SUBMISSION_TYPE_AVAILABLE;
|
||||||
|
workshop.submissiontypefile = AddonModWorkshopProvider.SUBMISSION_TYPE_AVAILABLE;
|
||||||
|
} else {
|
||||||
|
workshop.submissiontypetext = AddonModWorkshopProvider.SUBMISSION_TYPE_REQUIRED;
|
||||||
|
workshop.submissiontypefile = AddonModWorkshopProvider.SUBMISSION_TYPE_DISABLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return workshop;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ export class CoreAttachmentsComponent implements OnInit {
|
||||||
@Input() componentId: string | number; // Component ID.
|
@Input() componentId: string | number; // Component ID.
|
||||||
@Input() allowOffline: boolean | string; // Whether to allow selecting files in offline.
|
@Input() allowOffline: boolean | string; // Whether to allow selecting files in offline.
|
||||||
@Input() acceptedTypes: string; // List of supported filetypes. If undefined, all types supported.
|
@Input() acceptedTypes: string; // List of supported filetypes. If undefined, all types supported.
|
||||||
|
@Input() required: boolean; // Whether to display the required mark.
|
||||||
|
|
||||||
maxSizeReadable: string;
|
maxSizeReadable: string;
|
||||||
maxSubmissionsReadable: string;
|
maxSubmissionsReadable: string;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<ion-item text-wrap>
|
<ion-item text-wrap>
|
||||||
{{ 'core.maxsizeandattachments' | translate:{$a: {size: maxSizeReadable, attachments: maxSubmissionsReadable} } }}
|
{{ 'core.maxsizeandattachments' | translate:{$a: {size: maxSizeReadable, attachments: maxSubmissionsReadable} } }}
|
||||||
|
<span [core-mark-required]="required" class="core-mark-required"></span>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item text-wrap *ngIf="fileTypes && fileTypes.mimetypes && fileTypes.mimetypes.length">
|
<ion-item text-wrap *ngIf="fileTypes && fileTypes.mimetypes && fileTypes.mimetypes.length">
|
||||||
<p>{{ 'core.fileuploader.filesofthesetypes' | translate }}</p>
|
<p>{{ 'core.fileuploader.filesofthesetypes' | translate }}</p>
|
||||||
|
|
|
@ -427,6 +427,23 @@ export class CoreTextUtilsProvider {
|
||||||
return /<[a-z][\s\S]*>/i.test(text);
|
return /<[a-z][\s\S]*>/i.test(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if HTML content is blank.
|
||||||
|
*
|
||||||
|
* @param {string} content HTML content.
|
||||||
|
* @return {boolean} True if the string does not contain actual content: text, images, etc.
|
||||||
|
*/
|
||||||
|
htmlIsBlank(content: string): boolean {
|
||||||
|
if (!content) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.innerHTML = content;
|
||||||
|
|
||||||
|
return div.textContent === '' && div.querySelector('img, object, hr') === null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a text contains Unicode long chars.
|
* Check if a text contains Unicode long chars.
|
||||||
* Using as threshold Hex value D800
|
* Using as threshold Hex value D800
|
||||||
|
|
Loading…
Reference in New Issue