diff --git a/src/addon/mod/data/components/index/index.ts b/src/addon/mod/data/components/index/index.ts index 54c6d61cd..ac4d95546 100644 --- a/src/addon/mod/data/components/index/index.ts +++ b/src/addon/mod/data/components/index/index.ts @@ -327,9 +327,6 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp }); entries.entries.forEach((entry) => { - // Index contents by fieldid. - entry.contents = this.utils.arrayToObject(entry.contents, 'fieldid'); - if (typeof this.offlineActions[entry.id] != 'undefined') { promises.push(this.dataHelper.applyOfflineActions(entry, this.offlineActions[entry.id], this.fieldsArray)); } else { diff --git a/src/addon/mod/data/pages/edit/edit.ts b/src/addon/mod/data/pages/edit/edit.ts index 4ca834934..ce8ccd06a 100644 --- a/src/addon/mod/data/pages/edit/edit.ts +++ b/src/addon/mod/data/pages/edit/edit.ts @@ -158,9 +158,6 @@ export class AddonModDataEditPage { }).then((entry) => { if (entry) { entry = entry.entry; - - // Index contents by fieldid. - entry.contents = this.utils.arrayToObject(entry.contents, 'fieldid'); } else { entry = { contents: {} diff --git a/src/addon/mod/data/pages/entry/entry.ts b/src/addon/mod/data/pages/entry/entry.ts index 2c568ab8d..0ae32b2be 100644 --- a/src/addon/mod/data/pages/entry/entry.ts +++ b/src/addon/mod/data/pages/entry/entry.ts @@ -171,9 +171,6 @@ export class AddonModDataEntryPage implements OnDestroy { this.ratingInfo = entry.ratinginfo; entry = entry.entry; - // Index contents by fieldid. - entry.contents = this.utils.arrayToObject(entry.contents, 'fieldid'); - fieldsArray = this.utils.objectToArray(this.fields); return this.dataHelper.applyOfflineActions(entry, this.offlineActions, fieldsArray); diff --git a/src/addon/mod/data/providers/data.ts b/src/addon/mod/data/providers/data.ts index a50cf5156..31caaf80f 100644 --- a/src/addon/mod/data/providers/data.ts +++ b/src/addon/mod/data/providers/data.ts @@ -21,6 +21,67 @@ import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper'; import { AddonModDataOfflineProvider } from './offline'; import { AddonModDataFieldsDelegate } from './fields-delegate'; +import { CoreRatingInfo } from '@core/rating/providers/rating'; + +/** + * Database entry (online or offline). + */ +export interface AddonModDataEntry { + id: number; // Negative for offline entries. + userid: number; + groupid: number; + dataid: number; + timecreated: number; + timemodified: number; + approved: boolean; + canmanageentry: boolean; + fullname: string; + contents: AddonModDataEntryFields; + deleted?: boolean; // Entry is deleted offline. + hasOffline?: boolean; // Entry has offline actions. +} + +/** + * Entry field content. + */ +export interface AddonModDataEntryField { + fieldid: number; + content: string; + content1: string; + content2: string; + content3: string; + content4: string; + files: any[]; +} + +/** + * Entry contents indexed by field id. + */ +export interface AddonModDataEntryFields { + [fieldid: number]: AddonModDataEntryField; +} + +/** + * List of entries returned by web service and helper functions. + */ +export interface AddonModDataEntries { + entries: AddonModDataEntry[]; // Online entries. + totalcount: number; // Total count of online entries or found entries. + maxcount?: number; // Total count of online entries. Only returned when searching. + offlineEntries?: AddonModDataEntry[]; // Offline entries. + hasOfflineActions?: boolean; // Whether the database has offline data. + hasOfflineRatings?: boolean; // Whether the database has offline ratings. +} + +/** + * Subfield form data. + */ +export interface AddonModDataSubfieldData { + fieldid: number; + subfield?: string; + value?: string; // Value encoded in JSON. + files?: any[]; +} /** * Service that provides some features for databases. @@ -49,13 +110,13 @@ export class AddonModDataProvider { * @param {number} courseId Course ID. * @param {any} contents The fields data to be created. * @param {number} [groupId] Group id, 0 means that the function will determine the user group. - * @param {any} fields The fields that define the contents. + * @param {any[]} fields The fields that define the contents. * @param {string} [siteId] Site ID. If not defined, current site. * @param {boolean} [forceOffline] Force editing entry in offline. * @return {Promise} Promise resolved when the action is done. */ - addEntry(dataId: number, entryId: number, courseId: number, contents: any, groupId: number = 0, fields: any, siteId?: string, - forceOffline: boolean = false): Promise { + addEntry(dataId: number, entryId: number, courseId: number, contents: AddonModDataSubfieldData[], groupId: number = 0, + fields: any, siteId?: string, forceOffline: boolean = false): Promise { siteId = siteId || this.sitesProvider.getCurrentSiteId(); // Convenience function to store a data to be synchronized later. @@ -93,12 +154,12 @@ export class AddonModDataProvider { * Adds a new entry to a database. It does not cache calls. It will fail if offline or cannot connect. * * @param {number} dataId Database ID. - * @param {any} data The fields data to be created. + * @param {any[]} data The fields data to be created. * @param {number} [groupId] Group id, 0 means that the function will determine the user group. * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when the action is done. */ - addEntryOnline(dataId: number, data: any, groupId?: number, siteId?: string): Promise { + addEntryOnline(dataId: number, data: AddonModDataSubfieldData[], groupId?: number, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { const params = { databaseid: dataId, @@ -184,7 +245,7 @@ export class AddonModDataProvider { * @param {any} contents The contents data of the fields. * @return {any} Array of notifications if any or false. */ - protected checkFields(fields: any, contents: any): any { + protected checkFields(fields: any, contents: AddonModDataSubfieldData[]): any[] | false { const notifications = [], contentsIndexed = {}; @@ -289,13 +350,13 @@ export class AddonModDataProvider { * @param {number} dataId Database ID. * @param {number} entryId Entry ID. * @param {number} courseId Course ID. - * @param {any} contents The contents data to be updated. + * @param {any[]} contents The contents data to be updated. * @param {any} fields The fields that define the contents. * @param {string} [siteId] Site ID. If not defined, current site. * @param {boolean} forceOffline Force editing entry in offline. * @return {Promise} Promise resolved when the action is done. */ - editEntry(dataId: number, entryId: number, courseId: number, contents: any, fields: any, siteId?: string, + editEntry(dataId: number, entryId: number, courseId: number, contents: AddonModDataSubfieldData[], fields: any, siteId?: string, forceOffline: boolean = false): Promise { siteId = siteId || this.sitesProvider.getCurrentSiteId(); @@ -370,11 +431,11 @@ export class AddonModDataProvider { * Updates an existing entry. It does not cache calls. It will fail if offline or cannot connect. * * @param {number} entryId Entry ID. - * @param {any} data The fields data to be updated. + * @param {any[]} data The fields data to be updated. * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when the action is done. */ - editEntryOnline(entryId: number, data: number, siteId?: string): Promise { + editEntryOnline(entryId: number, data: AddonModDataSubfieldData[], siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { const params = { entryid: entryId, @@ -397,11 +458,11 @@ export class AddonModDataProvider { * @param {boolean} [forceCache] True to always get the value from cache, false otherwise. Default false. * @param {boolean} [ignoreCache] True if it should ignore cached data (it will always fail in offline or server down). * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} Promise resolved when done. + * @return {Promise} Promise resolved when done. */ fetchAllEntries(dataId: number, groupId: number = 0, sort: string = '0', order: string = 'DESC', perPage: number = AddonModDataProvider.PER_PAGE, forceCache: boolean = false, ignoreCache: boolean = false, - siteId?: string): Promise { + siteId?: string): Promise { siteId = siteId || this.sitesProvider.getCurrentSiteId(); return this.fetchEntriesRecursive(dataId, groupId, sort, order, perPage, forceCache, ignoreCache, [], 0, siteId); @@ -420,10 +481,10 @@ export class AddonModDataProvider { * @param {any} entries Entries already fetch (just to concatenate them). * @param {number} page Page of records to return. * @param {string} siteId Site ID. - * @return {Promise} Promise resolved when done. + * @return {Promise} Promise resolved when done. */ protected fetchEntriesRecursive(dataId: number, groupId: number, sort: string, order: string, perPage: number, - forceCache: boolean, ignoreCache: boolean, entries: any, page: number, siteId: string): Promise { + forceCache: boolean, ignoreCache: boolean, entries: any, page: number, siteId: string): Promise { return this.getEntries(dataId, groupId, sort, order, page, perPage, forceCache, ignoreCache, siteId) .then((result) => { entries = entries.concat(result.entries); @@ -595,11 +656,11 @@ export class AddonModDataProvider { * @param {boolean} [forceCache=false] True to always get the value from cache, false otherwise. Default false. * @param {boolean} [ignoreCache=false] True if it should ignore cached data (it'll always fail in offline or server down). * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} Promise resolved when the database is retrieved. + * @return {Promise} Promise resolved when the database is retrieved. */ getEntries(dataId: number, groupId: number = 0, sort: string = '0', order: string = 'DESC', page: number = 0, perPage: number = AddonModDataProvider.PER_PAGE, forceCache: boolean = false, ignoreCache: boolean = false, - siteId?: string): Promise { + siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { // Always use sort and order params to improve cache usage (entries are identified by params). const params = { @@ -622,7 +683,13 @@ export class AddonModDataProvider { preSets['emergencyCache'] = false; } - return site.read('mod_data_get_entries', params, preSets); + return site.read('mod_data_get_entries', params, preSets).then((response) => { + response.entries.forEach((entry) => { + entry.contents = this.utils.arrayToObject(entry.contents, 'fieldid'); + }); + + return response; + }); }); } @@ -654,9 +721,10 @@ export class AddonModDataProvider { * @param {number} entryId Entry ID. * @param {boolean} [ignoreCache=false] True if it should ignore cached data (it'll always fail in offline or server down). * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} Promise resolved when the database entry is retrieved. + * @return {Promise<{entry: AddonModDataEntry, ratinginfo: CoreRatingInfo}>} Promise resolved when the entry is retrieved. */ - getEntry(dataId: number, entryId: number, ignoreCache: boolean = false, siteId?: string): Promise { + getEntry(dataId: number, entryId: number, ignoreCache: boolean = false, siteId?: string): + Promise<{entry: AddonModDataEntry, ratinginfo: CoreRatingInfo}> { return this.sitesProvider.getSite(siteId).then((site) => { const params = { entryid: entryId, @@ -671,7 +739,11 @@ export class AddonModDataProvider { preSets['emergencyCache'] = false; } - return site.read('mod_data_get_entry', params, preSets); + return site.read('mod_data_get_entry', params, preSets).then((response) => { + response.entry.contents = this.utils.arrayToObject(response.entry.contents, 'fieldid'); + + return response; + }); }); } @@ -871,16 +943,16 @@ export class AddonModDataProvider { * @param {number} dataId The data instance id. * @param {number} [groupId=0] Group id, 0 means that the function will determine the user group. * @param {string} [search] Search text. It will be used if advSearch is not defined. - * @param {any} [advSearch] Advanced search data. + * @param {any[]} [advSearch] Advanced search data. * @param {string} [sort] Sort by this field. * @param {string} [order] The direction of the sorting. * @param {number} [page=0] Page of records to return. * @param {number} [perPage=PER_PAGE] Records per page to return. Default on AddonModDataProvider.PER_PAGE. * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} Promise resolved when the action is done. + * @return {Promise} Promise resolved when the action is done. */ searchEntries(dataId: number, groupId: number = 0, search?: string, advSearch?: any, sort?: string, order?: string, - page: number = 0, perPage: number = AddonModDataProvider.PER_PAGE, siteId?: string): Promise { + page: number = 0, perPage: number = AddonModDataProvider.PER_PAGE, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { const params = { databaseid: dataId, @@ -911,7 +983,13 @@ export class AddonModDataProvider { params['advsearch'] = advSearch; } - return site.read('mod_data_search_entries', params, preSets); + return site.read('mod_data_search_entries', params, preSets).then((response) => { + response.entries.forEach((entry) => { + entry.contents = this.utils.arrayToObject(entry.contents, 'fieldid'); + }); + + return response; + }); }); } } diff --git a/src/addon/mod/data/providers/helper.ts b/src/addon/mod/data/providers/helper.ts index c713f3674..930d63e15 100644 --- a/src/addon/mod/data/providers/helper.ts +++ b/src/addon/mod/data/providers/helper.ts @@ -18,8 +18,8 @@ import { CoreSitesProvider } from '@providers/sites'; import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; import { AddonModDataFieldsDelegate } from './fields-delegate'; -import { AddonModDataOfflineProvider } from './offline'; -import { AddonModDataProvider } from './data'; +import { AddonModDataOfflineProvider, AddonModDataOfflineAction } from './offline'; +import { AddonModDataProvider, AddonModDataEntry, AddonModDataEntryFields } from './data'; /** * Service that provides helper functions for datas. @@ -35,15 +35,19 @@ export class AddonModDataHelperProvider { /** * Returns the record with the offline actions applied. * - * @param {any} record Entry to modify. - * @param {any} offlineActions Offline data with the actions done. - * @param {any} fields Entry defined fields indexed by fieldid. - * @return {any} Modified entry. + * @param {AddonModDataEntry} record Entry to modify. + * @param {AddonModDataOfflineAction[]} offlineActions Offline data with the actions done. + * @param {any[]} fields Entry defined fields indexed by fieldid. + * @return {Promise} Promise resolved when done. */ - applyOfflineActions(record: any, offlineActions: any[], fields: any[]): any { + applyOfflineActions(record: AddonModDataEntry, offlineActions: AddonModDataOfflineAction[], fields: any[]): + Promise { const promises = []; offlineActions.forEach((action) => { + record.timemodified = action.timemodified; + record.hasOffline = true; + switch (action.action) { case 'approve': record.approved = true; @@ -56,6 +60,8 @@ export class AddonModDataHelperProvider { break; case 'add': case 'edit': + record.groupid = action.groupid; + const offlineContents = {}; action.fields.forEach((offlineContent) => { @@ -77,10 +83,12 @@ export class AddonModDataHelperProvider { promises.push(this.getStoredFiles(record.dataid, record.id, field.id).then((offlineFiles) => { record.contents[field.id] = this.fieldsDelegate.overrideData(field, record.contents[field.id], offlineContents[field.id], offlineFiles); + record.contents[field.id].fieldid = field.id; })); } else { record.contents[field.id] = this.fieldsDelegate.overrideData(field, record.contents[field.id], offlineContents[field.id]); + record.contents[field.id].fieldid = field.id; } }); break; @@ -97,15 +105,16 @@ export class AddonModDataHelperProvider { /** * Displays fields for being shown. * - * @param {string} template Template HMTL. - * @param {any[]} fields Fields that defines every content in the entry. - * @param {any} entry Entry. - * @param {number} offset Entry offset. - * @param {string} mode Mode list or show. - * @param {any} actions Actions that can be performed to the record. - * @return {string} Generated HTML. + * @param {string} template Template HMTL. + * @param {any[]} fields Fields that defines every content in the entry. + * @param {any} entry Entry. + * @param {number} offset Entry offset. + * @param {string} mode Mode list or show. + * @param {AddonModDataOfflineAction[]} actions Actions that can be performed to the record. + * @return {string} Generated HTML. */ - displayShowFields(template: string, fields: any[], entry: any, offset: number, mode: string, actions: any): string { + displayShowFields(template: string, fields: any[], entry: any, offset: number, mode: string, + actions: AddonModDataOfflineAction[]): string { if (!template) { return ''; } @@ -256,17 +265,17 @@ export class AddonModDataHelperProvider { * Retrieve the entered data in the edit form. * We don't use ng-model because it doesn't detect changes done by JavaScript. * - * @param {any} inputData Array with the entered form values. - * @param {Array} fields Fields that defines every content in the entry. - * @param {number} [dataId] Database Id. If set, files will be uploaded and itemId set. - * @param {number} entryId Entry Id. - * @param {any} entryContents Original entry contents indexed by field id. - * @param {boolean} offline True to prepare the data for an offline uploading, false otherwise. - * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} That contains object with the answers. + * @param {any} inputData Array with the entered form values. + * @param {Array} fields Fields that defines every content in the entry. + * @param {number} [dataId] Database Id. If set, files will be uploaded and itemId set. + * @param {number} entryId Entry Id. + * @param {AddonModDataEntryFields} entryContents Original entry contents. + * @param {boolean} offline True to prepare the data for an offline uploading, false otherwise. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} That contains object with the answers. */ - getEditDataFromForm(inputData: any, fields: any, dataId: number, entryId: number, entryContents: any, offline: boolean = false, - siteId?: string): Promise { + getEditDataFromForm(inputData: any, fields: any, dataId: number, entryId: number, entryContents: AddonModDataEntryFields, + offline: boolean = false, siteId?: string): Promise { if (!inputData) { return Promise.resolve({}); } @@ -322,13 +331,13 @@ export class AddonModDataHelperProvider { /** * Retrieve the temp files to be updated. * - * @param {any} inputData Array with the entered form values. - * @param {Array} fields Fields that defines every content in the entry. - * @param {number} [dataId] Database Id. If set, fils will be uploaded and itemId set. - * @param {any} entryContents Original entry contents indexed by field id. - * @return {Promise} That contains object with the files. + * @param {any} inputData Array with the entered form values. + * @param {any[]} fields Fields that defines every content in the entry. + * @param {number} [dataId] Database Id. If set, fils will be uploaded and itemId set. + * @param {AddonModDataEntryFields} entryContents Original entry contents indexed by field id. + * @return {Promise} That contains object with the files. */ - getEditTmpFiles(inputData: any, fields: any, dataId: number, entryContents: any): Promise { + getEditTmpFiles(inputData: any, fields: any[], dataId: number, entryContents: AddonModDataEntryFields): Promise { if (!inputData) { return Promise.resolve([]); } @@ -403,13 +412,13 @@ export class AddonModDataHelperProvider { /** * Check if data has been changed by the user. * - * @param {any} inputData Array with the entered form values. - * @param {any} fields Fields that defines every content in the entry. - * @param {number} [dataId] Database Id. If set, fils will be uploaded and itemId set. - * @param {any} entryContents Original entry contents indexed by field id. - * @return {Promise} True if changed, false if not. + * @param {any} inputData Object with the entered form values. + * @param {any[]} fields Fields that defines every content in the entry. + * @param {number} [dataId] Database Id. If set, fils will be uploaded and itemId set. + * @param {AddonModDataEntryFields} entryContents Original entry contents indexed by field id. + * @return {Promise} True if changed, false if not. */ - hasEditDataChanged(inputData: any, fields: any, dataId: number, entryContents: any): Promise { + hasEditDataChanged(inputData: any, fields: any[], dataId: number, entryContents: AddonModDataEntryFields): Promise { const promises = fields.map((field) => { return this.fieldsDelegate.hasFieldDataChanged(field, inputData, entryContents[field.id]); }); diff --git a/src/addon/mod/data/providers/offline.ts b/src/addon/mod/data/providers/offline.ts index 0c773f978..92e38cb25 100644 --- a/src/addon/mod/data/providers/offline.ts +++ b/src/addon/mod/data/providers/offline.ts @@ -19,6 +19,20 @@ import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreFileProvider } from '@providers/file'; import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; import { SQLiteDB } from '@classes/sqlitedb'; +import { AddonModDataSubfieldData } from './data'; + +/** + * Entry action stored offline. + */ +export interface AddonModDataOfflineAction { + dataid: number; + courseid: number; + groupid: number; + action: string; + entryid: number; // Negative for offline entries. + fields: AddonModDataSubfieldData[]; + timemodified: number; +} /** * Service to handle Offline data. @@ -175,10 +189,10 @@ export class AddonModDataOfflineProvider { /** * Get all the stored entry data from all the databases. * - * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} Promise resolved with entries. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with entries. */ - getAllEntries(siteId?: string): Promise { + getAllEntries(siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { return site.getDb().getAllRecords(AddonModDataOfflineProvider.DATA_ENTRY_TABLE); }).then((entries) => { @@ -189,11 +203,11 @@ export class AddonModDataOfflineProvider { /** * Get all the stored entry data from a certain database. * - * @param {number} dataId Database ID. - * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} Promise resolved with entries. + * @param {number} dataId Database ID. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with entries. */ - getDatabaseEntries(dataId: number, siteId?: string): Promise { + getDatabaseEntries(dataId: number, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { return site.getDb().getRecords(AddonModDataOfflineProvider.DATA_ENTRY_TABLE, {dataid: dataId}); }).then((entries) => { @@ -208,9 +222,9 @@ export class AddonModDataOfflineProvider { * @param {number} entryId Database entry Id. * @param {string} action Action to be done * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} Promise resolved with entry. + * @return {Promise} Promise resolved with entry. */ - getEntry(dataId: number, entryId: number, action: string, siteId?: string): Promise { + getEntry(dataId: number, entryId: number, action: string, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { return site.getDb().getRecord(AddonModDataOfflineProvider.DATA_ENTRY_TABLE, {dataid: dataId, entryid: entryId, action: action}); @@ -225,9 +239,9 @@ export class AddonModDataOfflineProvider { * @param {number} dataId Database ID. * @param {number} entryId Database entry Id. * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} Promise resolved with entry actions. + * @return {Promise} Promise resolved with entry actions. */ - getEntryActions(dataId: number, entryId: number, siteId?: string): Promise { + getEntryActions(dataId: number, entryId: number, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { return site.getDb().getRecords(AddonModDataOfflineProvider.DATA_ENTRY_TABLE, {dataid: dataId, entryid: entryId}); }).then((entries) => { @@ -286,10 +300,10 @@ export class AddonModDataOfflineProvider { /** * Parse "fields" of an offline record. * - * @param {any} record Record object - * @return {any} Record object with columns parsed. + * @param {any} record Record object + * @return {AddonModDataOfflineAction} Record object with columns parsed. */ - protected parseRecord(record: any): any { + protected parseRecord(record: any): AddonModDataOfflineAction { record.fields = this.textUtils.parseJSON(record.fields); return record; @@ -308,8 +322,8 @@ export class AddonModDataOfflineProvider { * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved if stored, rejected if failure. */ - saveEntry(dataId: number, entryId: number, action: string, courseId: number, groupId?: number, fields?: any[], - timemodified?: number, siteId?: string): Promise { + saveEntry(dataId: number, entryId: number, action: string, courseId: number, groupId?: number, + fields?: AddonModDataSubfieldData[], timemodified?: number, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { timemodified = timemodified || new Date().getTime(); diff --git a/src/addon/mod/data/providers/prefetch-handler.ts b/src/addon/mod/data/providers/prefetch-handler.ts index 5586ef558..a0a0d297a 100644 --- a/src/addon/mod/data/providers/prefetch-handler.ts +++ b/src/addon/mod/data/providers/prefetch-handler.ts @@ -25,7 +25,7 @@ import { CoreCommentsProvider } from '@core/comments/providers/comments'; import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; import { CoreRatingProvider } from '@core/rating/providers/rating'; -import { AddonModDataProvider } from './data'; +import { AddonModDataProvider, AddonModDataEntry } from './data'; import { AddonModDataSyncProvider } from './sync'; import { AddonModDataHelperProvider } from './helper'; @@ -57,10 +57,10 @@ export class AddonModDataPrefetchHandler extends CoreCourseActivityPrefetchHandl * @param {boolean} [forceCache] True to always get the value from cache, false otherwise. Default false. * @param {boolean} [ignoreCache] True if it should ignore cached data (it will always fail in offline or server down). * @param {string} [siteId] Site ID. - * @return {Promise} All unique entries. + * @return {Promise} All unique entries. */ protected getAllUniqueEntries(dataId: number, groups: any[], forceCache: boolean = false, ignoreCache: boolean = false, - siteId?: string): Promise { + siteId?: string): Promise { const promises = groups.map((group) => { return this.dataProvider.fetchAllEntries(dataId, group.id, undefined, undefined, undefined, forceCache, ignoreCache, siteId); @@ -139,14 +139,14 @@ export class AddonModDataPrefetchHandler extends CoreCourseActivityPrefetchHandl /** * Returns the file contained in the entries. * - * @param {any[]} entries List of entries to get files from. - * @return {any[]} List of files. + * @param {AddonModDataEntry[]} entries List of entries to get files from. + * @return {any[]} List of files. */ - protected getEntriesFiles(entries: any[]): any[] { + protected getEntriesFiles(entries: AddonModDataEntry[]): any[] { let files = []; entries.forEach((entry) => { - entry.contents.forEach((content) => { + this.utils.objectToArray(entry.contents).forEach((content) => { files = files.concat(content.files); }); }); diff --git a/src/addon/mod/data/providers/sync.ts b/src/addon/mod/data/providers/sync.ts index 5bfe991bd..03590485a 100644 --- a/src/addon/mod/data/providers/sync.ts +++ b/src/addon/mod/data/providers/sync.ts @@ -20,7 +20,7 @@ import { CoreAppProvider } from '@providers/app'; import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreTimeUtilsProvider } from '@providers/utils/time'; -import { AddonModDataOfflineProvider } from './offline'; +import { AddonModDataOfflineProvider, AddonModDataOfflineAction } from './offline'; import { AddonModDataProvider } from './data'; import { AddonModDataHelperProvider } from './helper'; import { CoreEventsProvider } from '@providers/events'; @@ -174,7 +174,7 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider { // No offline data found, return empty object. return []; }); - }).then((offlineActions) => { + }).then((offlineActions: AddonModDataOfflineAction[]) => { if (!offlineActions.length) { // Nothing to sync. return; @@ -226,13 +226,13 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider { /** * Synchronize an entry. * - * @param {any} data Database. - * @param {any} entryActions Entry actions. - * @param {any} result Object with the result of the sync. - * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} Promise resolved if success, rejected otherwise. + * @param {any} data Database. + * @param {AddonModDataOfflineAction[]} entryActions Entry actions. + * @param {any} result Object with the result of the sync. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved if success, rejected otherwise. */ - protected syncEntry(data: any, entryActions: any[], result: any, siteId?: string): Promise { + protected syncEntry(data: any, entryActions: AddonModDataOfflineAction[], result: any, siteId?: string): Promise { let discardError, timePromise, entryId = 0,