Merge pull request #1548 from albertgasset/MOBILE-2611

Mobile 2611
main
Juan Leyva 2018-10-03 16:56:50 +02:00 committed by GitHub
commit e0a53d4a08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 82 additions and 9 deletions

View File

@ -19,12 +19,12 @@
<ion-input name="title" type="text" [placeholder]="'addon.mod_workshop.submissiontitle' | translate" formControlName="title"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>{{ 'addon.mod_workshop.submissioncontent' | translate }}</ion-label>
<ion-item *ngIf="textAvailable">
<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>
</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>
</core-loading>
</ion-content>

View File

@ -62,6 +62,10 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
protected siteId: string;
protected workshop: any;
protected isDestroyed = false;
protected textAvailable = false;
protected textRequired = false;
protected fileAvailable = false;
protected fileRequired = false;
constructor(navParams: NavParams, sitesProvider: CoreSitesProvider, protected fileUploaderProvider: CoreFileUploaderProvider,
protected workshopProvider: AddonModWorkshopProvider, protected workshopOffline: AddonModWorkshopOfflineProvider,
@ -132,6 +136,12 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
protected fetchSubmissionData(): Promise<void> {
return this.workshopProvider.getWorkshop(this.courseId, this.module.id).then((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) {
this.editing = true;
@ -220,8 +230,19 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
protected getInputData(): any {
const submissionId = this.submission.id || 'newsub';
const values = this.editForm.value;
values['attachmentfiles'] = this.fileSessionprovider.getFiles(this.component, this.workshopId + '_' + submissionId) || [];
const values = {
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;
}
@ -242,13 +263,17 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
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;
}
if (this.fileAvailable) {
return this.fileUploaderProvider.areFileListDifferent(inputData.attachmentfiles, this.originalData.attachmentfiles);
}
return false;
}
/**
* Pull to refresh.
*
@ -300,7 +325,10 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
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');
return Promise.reject(null);
@ -313,7 +341,9 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
submissionId = this.submission.id;
// Add some HTML to the message if needed.
if (this.textAvailable) {
inputData.content = this.textUtils.formatHtmlLines(inputData.content);
}
// Upload attachments first if any.
allowOffline = !inputData.attachmentfiles.length;
@ -327,6 +357,10 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
return this.workshopHelper.uploadOrStoreSubmissionFiles(this.workshopId, this.submission.id,
inputData.attachmentfiles, this.editing, saveOffline);
}).then((attachmentsId) => {
if (!saveOffline && !this.fileAvailable) {
attachmentsId = null;
}
if (this.editing) {
if (saveOffline) {
// Save submission in offline.

View File

@ -318,6 +318,10 @@ export class AddonModWorkshopSyncProvider extends CoreSyncBaseProvider {
}
return fileProm.then((attachmentsId) => {
if (workshop.submissiontypefile == AddonModWorkshopProvider.SUBMISSION_TYPE_DISABLED) {
attachmentsId = null;
}
// Perform the action.
switch (action.action) {
case 'add':

View File

@ -34,6 +34,9 @@ export class AddonModWorkshopProvider {
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;
static SUBMISSION_CHANGED = 'addon_mod_workshop_submission_changed';
static ASSESSMENT_SAVED = 'addon_mod_workshop_assessment_saved';
@ -223,6 +226,19 @@ export class AddonModWorkshopProvider {
}
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;
});
});
}

View File

@ -45,6 +45,7 @@ export class CoreAttachmentsComponent implements OnInit {
@Input() componentId: string | number; // Component ID.
@Input() allowOffline: boolean | string; // Whether to allow selecting files in offline.
@Input() acceptedTypes: string; // List of supported filetypes. If undefined, all types supported.
@Input() required: boolean; // Whether to display the required mark.
maxSizeReadable: string;
maxSubmissionsReadable: string;

View File

@ -1,5 +1,6 @@
<ion-item text-wrap>
{{ 'core.maxsizeandattachments' | translate:{$a: {size: maxSizeReadable, attachments: maxSubmissionsReadable} } }}
<span [core-mark-required]="required" class="core-mark-required"></span>
</ion-item>
<ion-item text-wrap *ngIf="fileTypes && fileTypes.mimetypes && fileTypes.mimetypes.length">
<p>{{ 'core.fileuploader.filesofthesetypes' | translate }}</p>

View File

@ -427,6 +427,23 @@ export class CoreTextUtilsProvider {
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.
* Using as threshold Hex value D800