From c770fb90142d01667d92ae769382ecda3d7e23c8 Mon Sep 17 00:00:00 2001 From: Albert Gasset Date: Mon, 1 Oct 2018 17:49:55 +0200 Subject: [PATCH 1/3] MOBILE-2611 utils: Function to check whether HTML content is blank --- src/providers/utils/text.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/providers/utils/text.ts b/src/providers/utils/text.ts index 6fa91d8be..3ee32224e 100644 --- a/src/providers/utils/text.ts +++ b/src/providers/utils/text.ts @@ -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 From 112eb7b5f99c10acc3d7fb07bb2d4bbbbc9a1434 Mon Sep 17 00:00:00 2001 From: Albert Gasset Date: Mon, 1 Oct 2018 17:53:14 +0200 Subject: [PATCH 2/3] MOBILE-2611 attachments: Parameter to display required mark --- src/components/attachments/attachments.ts | 1 + src/components/attachments/core-attachments.html | 1 + 2 files changed, 2 insertions(+) diff --git a/src/components/attachments/attachments.ts b/src/components/attachments/attachments.ts index 80dc5bb5e..a44eb6bb3 100644 --- a/src/components/attachments/attachments.ts +++ b/src/components/attachments/attachments.ts @@ -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; diff --git a/src/components/attachments/core-attachments.html b/src/components/attachments/core-attachments.html index 9131826d2..7a1abcda8 100644 --- a/src/components/attachments/core-attachments.html +++ b/src/components/attachments/core-attachments.html @@ -1,5 +1,6 @@ {{ 'core.maxsizeandattachments' | translate:{$a: {size: maxSizeReadable, attachments: maxSubmissionsReadable} } }} +

{{ 'core.fileuploader.filesofthesetypes' | translate }}

From 34a18c15ebb9d4c6e8b9cbe1feeb7b85919013ba Mon Sep 17 00:00:00 2001 From: Albert Gasset Date: Mon, 1 Oct 2018 17:53:55 +0200 Subject: [PATCH 3/3] MOBILE-2611 workshop: Support new submission type setting --- .../edit-submission/edit-submission.html | 6 +-- .../pages/edit-submission/edit-submission.ts | 46 ++++++++++++++++--- src/addon/mod/workshop/providers/sync.ts | 4 ++ src/addon/mod/workshop/providers/workshop.ts | 16 +++++++ 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/addon/mod/workshop/pages/edit-submission/edit-submission.html b/src/addon/mod/workshop/pages/edit-submission/edit-submission.html index 4b0f8ce69..cbfb44ba1 100644 --- a/src/addon/mod/workshop/pages/edit-submission/edit-submission.html +++ b/src/addon/mod/workshop/pages/edit-submission/edit-submission.html @@ -19,12 +19,12 @@
- - {{ 'addon.mod_workshop.submissioncontent' | translate }} + + {{ 'addon.mod_workshop.submissioncontent' | translate }} - + diff --git a/src/addon/mod/workshop/pages/edit-submission/edit-submission.ts b/src/addon/mod/workshop/pages/edit-submission/edit-submission.ts index 6afeff9a8..3409680a1 100644 --- a/src/addon/mod/workshop/pages/edit-submission/edit-submission.ts +++ b/src/addon/mod/workshop/pages/edit-submission/edit-submission.ts @@ -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 { 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,11 +263,15 @@ 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; } - return this.fileUploaderProvider.areFileListDifferent(inputData.attachmentfiles, this.originalData.attachmentfiles); + if (this.fileAvailable) { + return this.fileUploaderProvider.areFileListDifferent(inputData.attachmentfiles, this.originalData.attachmentfiles); + } + + return false; } /** @@ -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. - inputData.content = this.textUtils.formatHtmlLines(inputData.content); + 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. diff --git a/src/addon/mod/workshop/providers/sync.ts b/src/addon/mod/workshop/providers/sync.ts index 2b3990e70..050ead192 100644 --- a/src/addon/mod/workshop/providers/sync.ts +++ b/src/addon/mod/workshop/providers/sync.ts @@ -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': diff --git a/src/addon/mod/workshop/providers/workshop.ts b/src/addon/mod/workshop/providers/workshop.ts index 5a1a1c5c3..8c22710ef 100644 --- a/src/addon/mod/workshop/providers/workshop.ts +++ b/src/addon/mod/workshop/providers/workshop.ts @@ -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; }); }); }