diff --git a/src/addon/mod/data/components/action/action.ts b/src/addon/mod/data/components/action/action.ts index 32be60ec3..9e96c3d1a 100644 --- a/src/addon/mod/data/components/action/action.ts +++ b/src/addon/mod/data/components/action/action.ts @@ -12,10 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. import { Component, Input, OnInit, Injector } from '@angular/core'; +import { NavController } from 'ionic-angular'; import { CoreEventsProvider } from '@providers/events'; import { AddonModDataProvider } from '../../providers/data'; +import { AddonModDataHelperProvider } from '../../providers/helper'; import { AddonModDataOfflineProvider } from '../../providers/offline'; import { CoreSitesProvider } from '@providers/sites'; +import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper'; import { CoreUserProvider } from '@core/user/providers/user'; /** @@ -30,6 +33,8 @@ export class AddonModDataActionComponent implements OnInit { @Input() action: string; // The field to render. @Input() entry?: any; // The value of the field. @Input() database: any; // Database object. + @Input() module: any; // Module object. + @Input() group: number; // Module object. @Input() offset?: number; // Offset of the entry. siteId: string; @@ -39,11 +44,72 @@ export class AddonModDataActionComponent implements OnInit { constructor(protected injector: Injector, protected dataProvider: AddonModDataProvider, protected dataOffline: AddonModDataOfflineProvider, protected eventsProvider: CoreEventsProvider, - sitesProvider: CoreSitesProvider, protected userProvider: CoreUserProvider) { + sitesProvider: CoreSitesProvider, protected userProvider: CoreUserProvider, private navCtrl: NavController, + protected linkHelper: CoreContentLinksHelperProvider, private dataHelper: AddonModDataHelperProvider) { this.rootUrl = sitesProvider.getCurrentSite().getURL(); this.siteId = sitesProvider.getCurrentSiteId(); } + /** + * Component being initialized. + */ + ngOnInit(): void { + if (this.action == 'userpicture') { + this.userProvider.getProfile(this.entry.userid, this.database.courseid).then((profile) => { + this.userPicture = profile.profileimageurl; + }); + } + } + + /** + * Approve the entry. + */ + approveEntry(): void { + this.dataHelper.approveOrDisapproveEntry(this.database.id, this.entry.id, true, this.database.courseid); + } + + /** + * Show confirmation modal for deleting the entry. + */ + deleteEntry(): void { + this.dataHelper.showDeleteEntryModal(this.database.id, this.entry.id, this.database.courseid); + } + + /** + * Disapprove the entry. + */ + disapproveEntry(): void { + this.dataHelper.approveOrDisapproveEntry(this.database.id, this.entry.id, false, this.database.courseid); + } + + /** + * Go to the edit page of the entry. + */ + editEntry(): void { + const pageParams = { + courseId: this.database.course, + module: this.module, + entryId: this.entry.id + }; + + this.linkHelper.goInSite(this.navCtrl, 'AddonModDataEditPage', pageParams); + } + + /** + * Go to the view page of the entry. + */ + viewEntry(): void { + const pageParams: any = { + courseId: this.database.course, + module: this.module, + entryId: this.entry.id, + group: this.group, + offset: this.offset + }; + + this.linkHelper.goInSite(this.navCtrl, 'AddonModDataEntryPage', pageParams); + } + /** * Undo delete action. * @@ -60,37 +126,4 @@ export class AddonModDataActionComponent implements OnInit { this.eventsProvider.trigger(AddonModDataProvider.ENTRY_CHANGED, {dataId: dataId, entryId: entryId}, this.siteId); }); } - - /** - * Component being initialized. - */ - ngOnInit(): void { - switch (this.action) { - case 'more': - this.url = this.rootUrl + '/mod/data/view.php?d= ' + this.entry.dataid + '&rid=' + this.entry.id; - if (typeof this.offset == 'number') { - this.url += '&mode=single&page=' + this.offset; - } - break; - case 'edit': - this.url = this.rootUrl + '/mod/data/edit.php?d= ' + this.entry.dataid + '&rid=' + this.entry.id; - break; - case 'delete': - this.url = this.rootUrl + '/mod/data/view.php?d= ' + this.entry.dataid + '&delete=' + this.entry.id; - break; - case 'approve': - this.url = this.rootUrl + '/mod/data/view.php?d= ' + this.entry.dataid + '&approve=' + this.entry.id; - break; - case 'disapprove': - this.url = this.rootUrl + '/mod/data/view.php?d= ' + this.entry.dataid + '&disapprove=' + this.entry.id; - break; - case 'userpicture': - this.userProvider.getProfile(this.entry.userid, this.database.courseid).then((profile) => { - this.userPicture = profile.profileimageurl; - }); - break; - default: - break; - } - } } diff --git a/src/addon/mod/data/components/action/addon-mod-data-action.html b/src/addon/mod/data/components/action/addon-mod-data-action.html index 2faa09162..41a44e5fa 100644 --- a/src/addon/mod/data/components/action/addon-mod-data-action.html +++ b/src/addon/mod/data/components/action/addon-mod-data-action.html @@ -1,12 +1,12 @@ - + - + - + @@ -14,11 +14,11 @@ - + - + diff --git a/src/addon/mod/data/providers/approve-link-handler.ts b/src/addon/mod/data/providers/approve-link-handler.ts index 5e7a88a7d..5084b8fb3 100644 --- a/src/addon/mod/data/providers/approve-link-handler.ts +++ b/src/addon/mod/data/providers/approve-link-handler.ts @@ -16,9 +16,7 @@ import { Injectable } from '@angular/core'; import { CoreContentLinksHandlerBase } from '@core/contentlinks/classes/base-handler'; import { CoreContentLinksAction } from '@core/contentlinks/providers/delegate'; import { AddonModDataProvider } from './data'; -import { CoreCourseProvider } from '@core/course/providers/course'; -import { CoreDomUtilsProvider } from '@providers/utils/dom'; -import { CoreEventsProvider } from '@providers/events'; +import { AddonModDataHelperProvider } from './helper'; /** * Content links handler for database approve/disapprove entry. @@ -30,29 +28,10 @@ export class AddonModDataApproveLinkHandler extends CoreContentLinksHandlerBase featureName = 'CoreCourseModuleDelegate_AddonModData'; pattern = /\/mod\/data\/view\.php.*([\?\&](d|approve|disapprove)=\d+)/; - constructor(private dataProvider: AddonModDataProvider, private courseProvider: CoreCourseProvider, - private domUtils: CoreDomUtilsProvider, private eventsProvider: CoreEventsProvider) { + constructor(private dataProvider: AddonModDataProvider, private dataHelper: AddonModDataHelperProvider) { super(); } - /** - * Convenience function to help get courseId. - * - * @param {number} dataId Database Id. - * @param {string} siteId Site Id, if not set, current site will be used. - * @param {number} courseId Course Id if already set. - * @return {Promise} Resolved with course Id when done. - */ - protected getActivityCourseIdIfNotSet(dataId: number, siteId: string, courseId: number): Promise { - if (courseId) { - return Promise.resolve(courseId); - } - - return this.courseProvider.getModuleBasicInfoByInstance(dataId, 'data', siteId).then((module) => { - return module.course; - }); - } - /** * Get the list of actions for a link (url). * @@ -66,34 +45,11 @@ export class AddonModDataApproveLinkHandler extends CoreContentLinksHandlerBase CoreContentLinksAction[] | Promise { return [{ action: (siteId, navCtrl?): void => { - const modal = this.domUtils.showModalLoading(), - dataId = parseInt(params.d, 10), + const dataId = parseInt(params.d, 10), entryId = parseInt(params.approve, 10) || parseInt(params.disapprove, 10), approve = parseInt(params.approve, 10) ? true : false; - this.getActivityCourseIdIfNotSet(dataId, siteId, courseId).then((cId) => { - courseId = cId; - - // Approve/disapprove entry. - return this.dataProvider.approveEntry(dataId, entryId, approve, courseId, siteId).catch((message) => { - this.domUtils.showErrorModalDefault(message, 'addon.mod_data.errorapproving', true); - - return Promise.reject(null); - }); - }).then(() => { - const promises = []; - promises.push(this.dataProvider.invalidateEntryData(dataId, entryId, siteId)); - promises.push(this.dataProvider.invalidateEntriesData(dataId, siteId)); - - return Promise.all(promises); - }).then(() => { - this.eventsProvider.trigger(AddonModDataProvider.ENTRY_CHANGED, {dataId: dataId, entryId: entryId}, siteId); - - this.domUtils.showToast(approve ? 'addon.mod_data.recordapproved' : 'addon.mod_data.recorddisapproved', true, - 3000); - }).finally(() => { - modal.dismiss(); - }); + this.dataHelper.approveOrDisapproveEntry(dataId, entryId, approve, courseId, siteId); } }]; } diff --git a/src/addon/mod/data/providers/delete-link-handler.ts b/src/addon/mod/data/providers/delete-link-handler.ts index 5ba8f1b31..8da37ba6b 100644 --- a/src/addon/mod/data/providers/delete-link-handler.ts +++ b/src/addon/mod/data/providers/delete-link-handler.ts @@ -13,13 +13,10 @@ // limitations under the License. import { Injectable } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; import { CoreContentLinksHandlerBase } from '@core/contentlinks/classes/base-handler'; import { CoreContentLinksAction } from '@core/contentlinks/providers/delegate'; import { AddonModDataProvider } from './data'; -import { CoreCourseProvider } from '@core/course/providers/course'; -import { CoreDomUtilsProvider } from '@providers/utils/dom'; -import { CoreEventsProvider } from '@providers/events'; +import { AddonModDataHelperProvider } from './helper'; /** * Content links handler for database delete entry. @@ -31,30 +28,10 @@ export class AddonModDataDeleteLinkHandler extends CoreContentLinksHandlerBase { featureName = 'CoreCourseModuleDelegate_AddonModData'; pattern = /\/mod\/data\/view\.php.*([\?\&](d|delete)=\d+)/; - constructor(private dataProvider: AddonModDataProvider, private courseProvider: CoreCourseProvider, - private domUtils: CoreDomUtilsProvider, private eventsProvider: CoreEventsProvider, - private translate: TranslateService) { + constructor(private dataProvider: AddonModDataProvider, private dataHelper: AddonModDataHelperProvider) { super(); } - /** - * Convenience function to help get courseId. - * - * @param {number} dataId Database Id. - * @param {string} siteId Site Id, if not set, current site will be used. - * @param {number} courseId Course Id if already set. - * @return {Promise} Resolved with course Id when done. - */ - protected getActivityCourseIdIfNotSet(dataId: number, siteId: string, courseId: number): Promise { - if (courseId) { - return Promise.resolve(courseId); - } - - return this.courseProvider.getModuleBasicInfoByInstance(dataId, 'data', siteId).then((module) => { - return module.course; - }); - } - /** * Get the list of actions for a link (url). * @@ -68,38 +45,10 @@ export class AddonModDataDeleteLinkHandler extends CoreContentLinksHandlerBase { CoreContentLinksAction[] | Promise { return [{ action: (siteId, navCtrl?): void => { + const dataId = parseInt(params.d, 10); + const entryId = parseInt(params.delete, 10); - this.domUtils.showConfirm(this.translate.instant('addon.mod_data.confirmdeleterecord')).then(() => { - const modal = this.domUtils.showModalLoading(), - dataId = parseInt(params.d, 10), - entryId = parseInt(params.delete, 10); - - return this.getActivityCourseIdIfNotSet(dataId, siteId, courseId).then((cId) => { - courseId = cId; - - // Delete entry. - return this.dataProvider.deleteEntry(dataId, entryId, courseId, siteId).catch((message) => { - this.domUtils.showErrorModalDefault(message, 'addon.mod_data.errordeleting', true); - - return Promise.reject(null); - }); - }).then(() => { - const promises = []; - promises.push(this.dataProvider.invalidateEntryData(dataId, entryId, siteId)); - promises.push(this.dataProvider.invalidateEntriesData(dataId, siteId)); - - return Promise.all(promises); - }).then(() => { - this.eventsProvider.trigger(AddonModDataProvider.ENTRY_CHANGED, {dataId: dataId, entryId: entryId, - deleted: true}, siteId); - - this.domUtils.showToast('addon.mod_data.recorddeleted', true, 3000); - }).finally(() => { - modal.dismiss(); - }); - }).catch(() => { - // Nothing to do. - }); + this.dataHelper.showDeleteEntryModal(dataId, entryId, courseId); } }]; } diff --git a/src/addon/mod/data/providers/helper.ts b/src/addon/mod/data/providers/helper.ts index c2428fabb..b5aaadcec 100644 --- a/src/addon/mod/data/providers/helper.ts +++ b/src/addon/mod/data/providers/helper.ts @@ -14,8 +14,12 @@ import { Injectable } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; +import { CoreEventsProvider } from '@providers/events'; import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreTextUtilsProvider } from '@providers/utils/text'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; import { AddonModDataFieldsDelegate } from './fields-delegate'; import { AddonModDataOfflineProvider, AddonModDataOfflineAction } from './offline'; @@ -32,7 +36,9 @@ export class AddonModDataHelperProvider { constructor(private sitesProvider: CoreSitesProvider, protected dataProvider: AddonModDataProvider, private translate: TranslateService, private fieldsDelegate: AddonModDataFieldsDelegate, private dataOffline: AddonModDataOfflineProvider, private fileUploaderProvider: CoreFileUploaderProvider, - private textUtils: CoreTextUtilsProvider, private ratingOffline: CoreRatingOfflineProvider) { } + private textUtils: CoreTextUtilsProvider, private eventsProvider: CoreEventsProvider, private utils: CoreUtilsProvider, + private domUtils: CoreDomUtilsProvider, private courseProvider: CoreCourseProvider, + private ratingOffline: CoreRatingOfflineProvider) {} /** * Returns the record with the offline actions applied. @@ -104,6 +110,46 @@ export class AddonModDataHelperProvider { }); } + /** + * Approve or disapprove a database entry. + * + * @param {number} dataId Database ID. + * @param {number} entryId Entry ID. + * @param {boolaen} approve True to approve, false to disapprove. + * @param {number} [courseId] Course ID. It not defined, it will be fetched. + * @param {string} [siteId] Site ID. If not defined, current site. + */ + approveOrDisapproveEntry(dataId: number, entryId: number, approve: boolean, courseId?: number, siteId?: string): void { + siteId = siteId || this.sitesProvider.getCurrentSiteId(); + + const modal = this.domUtils.showModalLoading('core.sending', true); + + this.getActivityCourseIdIfNotSet(dataId, courseId, siteId).then((courseId) => { + // Approve/disapprove entry. + return this.dataProvider.approveEntry(dataId, entryId, approve, courseId, siteId).catch((message) => { + this.domUtils.showErrorModalDefault(message, 'addon.mod_data.errorapproving', true); + + return Promise.reject(null); + }); + }).then(() => { + const promises = []; + promises.push(this.dataProvider.invalidateEntryData(dataId, entryId, siteId)); + promises.push(this.dataProvider.invalidateEntriesData(dataId, siteId)); + + return Promise.all(promises).catch(() => { + // Ignore errors. + }); + }).then(() => { + this.eventsProvider.trigger(AddonModDataProvider.ENTRY_CHANGED, {dataId: dataId, entryId: entryId}, siteId); + + this.domUtils.showToast(approve ? 'addon.mod_data.recordapproved' : 'addon.mod_data.recorddisapproved', true, 3000); + }).catch(() => { + // Ignore error, it was already displayed. + }).finally(() => { + modal.dismiss(); + }); + } + /** * Displays fields for being shown. * @@ -146,8 +192,8 @@ export class AddonModDataHelperProvider { } else if (action == 'approvalstatus') { render = this.translate.instant('addon.mod_data.' + (entry.approved ? 'approved' : 'notapproved')); } else { - render = ''; + render = ''; } template = template.replace(replace, render); } else { @@ -337,6 +383,24 @@ export class AddonModDataHelperProvider { }; } + /** + * Convenience function to get the course id of the database. + * + * @param {number} dataId Database id. + * @param {number} [courseId] Course id, if known. + * @param {string} [siteId] Site id, if not set, current site will be used. + * @return {Promise} Resolved with course Id when done. + */ + protected getActivityCourseIdIfNotSet(dataId: number, courseId?: number, siteId?: string): Promise { + if (courseId) { + return Promise.resolve(courseId); + } + + return this.courseProvider.getModuleBasicInfoByInstance(dataId, 'data', siteId).then((module) => { + return module.course; + }); + } + /** * Returns the default template of a certain type. * @@ -543,6 +607,45 @@ export class AddonModDataHelperProvider { }); } + /** + * Displays a confirmation modal for deleting an entry. + * + * @param {number} dataId Database ID. + * @param {number} entryId Entry ID. + * @param {number} [courseId] Course ID. It not defined, it will be fetched. + * @param {string} [siteId] Site ID. If not defined, current site. + */ + showDeleteEntryModal(dataId: number, entryId: number, courseId?: number, siteId?: string): void { + siteId = siteId || this.sitesProvider.getCurrentSiteId(); + + this.domUtils.showConfirm(this.translate.instant('addon.mod_data.confirmdeleterecord')).then(() => { + const modal = this.domUtils.showModalLoading(); + + return this.getActivityCourseIdIfNotSet(dataId, courseId, siteId).then((courseId) => { + return this.dataProvider.deleteEntry(dataId, entryId, courseId, siteId); + }).catch((message) => { + this.domUtils.showErrorModalDefault(message, 'addon.mod_data.errordeleting', true); + + return Promise.reject(null); + }).then(() => { + return this.utils.allPromises([ + this.dataProvider.invalidateEntryData(dataId, entryId, siteId), + this.dataProvider.invalidateEntriesData(dataId, siteId) + ]).catch(() => { + // Ignore errors. + }); + }).then(() => { + this.eventsProvider.trigger(AddonModDataProvider.ENTRY_CHANGED, {dataId, entryId, deleted: true}, siteId); + + this.domUtils.showToast('addon.mod_data.recorddeleted', true, 3000); + }).finally(() => { + modal.dismiss(); + }); + }).catch(() => { + // Ignore error, it was already displayed. + }); + } + /** * Given a list of files (either online files or local files), store the local files in a local folder * to be submitted later.