MOBILE-3320 database: Fix issues adding offline entries
parent
7ace30fa80
commit
ce4f4356c4
|
@ -71,7 +71,7 @@ export class AddonModDataSearchComponent implements OnInit {
|
||||||
this.search.advanced?.forEach((field) => {
|
this.search.advanced?.forEach((field) => {
|
||||||
if (typeof field != 'undefined') {
|
if (typeof field != 'undefined') {
|
||||||
this.advancedIndexed[field.name] = field.value
|
this.advancedIndexed[field.name] = field.value
|
||||||
? CoreTextUtils.parseJSON(field.value)
|
? CoreTextUtils.parseJSON(field.value, '')
|
||||||
: '';
|
: '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -112,7 +112,8 @@ export class AddonModDataFieldFileHandlerService implements AddonModDataFieldHan
|
||||||
offlineContent: CoreFormFields,
|
offlineContent: CoreFormFields,
|
||||||
offlineFiles?: FileEntry[],
|
offlineFiles?: FileEntry[],
|
||||||
): AddonModDataEntryField {
|
): AddonModDataEntryField {
|
||||||
const uploadedFilesResult: CoreFileUploaderStoreFilesResult = <CoreFileUploaderStoreFilesResult>offlineContent?.file;
|
const uploadedFilesResult: CoreFileUploaderStoreFilesResult | undefined =
|
||||||
|
<CoreFileUploaderStoreFilesResult | undefined> offlineContent?.file;
|
||||||
|
|
||||||
if (uploadedFilesResult && uploadedFilesResult.offline > 0 && offlineFiles && offlineFiles?.length > 0) {
|
if (uploadedFilesResult && uploadedFilesResult.offline > 0 && offlineFiles && offlineFiles?.length > 0) {
|
||||||
originalContent.content = offlineFiles[0].name;
|
originalContent.content = offlineFiles[0].name;
|
||||||
|
|
|
@ -121,8 +121,8 @@ export class AddonModDataFieldLatlongHandlerService implements AddonModDataField
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string>): AddonModDataEntryField {
|
overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string>): AddonModDataEntryField {
|
||||||
originalContent.content = offlineContent[0] || '';
|
originalContent.content = offlineContent['0'] || '';
|
||||||
originalContent.content1 = offlineContent[1] || '';
|
originalContent.content1 = offlineContent['1'] || '';
|
||||||
|
|
||||||
return originalContent;
|
return originalContent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,8 @@ export class AddonModDataFieldPictureHandlerService implements AddonModDataField
|
||||||
offlineContent: CoreFormFields,
|
offlineContent: CoreFormFields,
|
||||||
offlineFiles?: FileEntry[],
|
offlineFiles?: FileEntry[],
|
||||||
): AddonModDataEntryField {
|
): AddonModDataEntryField {
|
||||||
const uploadedFilesResult: CoreFileUploaderStoreFilesResult = <CoreFileUploaderStoreFilesResult>offlineContent?.file;
|
const uploadedFilesResult: CoreFileUploaderStoreFilesResult | undefined =
|
||||||
|
<CoreFileUploaderStoreFilesResult | undefined> offlineContent?.file;
|
||||||
|
|
||||||
if (uploadedFilesResult && uploadedFilesResult.offline > 0 && offlineFiles && offlineFiles?.length > 0) {
|
if (uploadedFilesResult && uploadedFilesResult.offline > 0 && offlineFiles && offlineFiles?.length > 0) {
|
||||||
originalContent.content = offlineFiles[0].name;
|
originalContent.content = offlineFiles[0].name;
|
||||||
|
@ -165,7 +166,7 @@ export class AddonModDataFieldPictureHandlerService implements AddonModDataField
|
||||||
originalContent.files = [uploadedFilesResult.online[0]];
|
originalContent.files = [uploadedFilesResult.online[0]];
|
||||||
}
|
}
|
||||||
|
|
||||||
originalContent.content1 = <string>offlineContent.alttext || '';
|
originalContent.content1 = <string> offlineContent.alttext || '';
|
||||||
|
|
||||||
return originalContent;
|
return originalContent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { AddonModDataField, AddonModDataSubfieldData } from '@addons/mod/data/services/data';
|
import { AddonModDataEntryField, AddonModDataField, AddonModDataSubfieldData } from '@addons/mod/data/services/data';
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreFormFields } from '@singletons/form';
|
import { CoreFormFields } from '@singletons/form';
|
||||||
import { Translate, makeSingleton } from '@singletons';
|
import { Translate, makeSingleton } from '@singletons';
|
||||||
|
@ -59,5 +59,14 @@ export class AddonModDataFieldUrlHandlerService extends AddonModDataFieldTextHan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string>): AddonModDataEntryField {
|
||||||
|
originalContent.content = offlineContent['0'] || '';
|
||||||
|
|
||||||
|
return originalContent;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
export const AddonModDataFieldUrlHandler = makeSingleton(AddonModDataFieldUrlHandlerService);
|
export const AddonModDataFieldUrlHandler = makeSingleton(AddonModDataFieldUrlHandlerService);
|
||||||
|
|
|
@ -92,9 +92,9 @@ export class AddonModDataHelperProvider {
|
||||||
|
|
||||||
if (offlineContent.subfield) {
|
if (offlineContent.subfield) {
|
||||||
offlineContents[offlineContent.fieldid][offlineContent.subfield] =
|
offlineContents[offlineContent.fieldid][offlineContent.subfield] =
|
||||||
CoreTextUtils.parseJSON(offlineContent.value);
|
CoreTextUtils.parseJSON(offlineContent.value, '');
|
||||||
} else {
|
} else {
|
||||||
offlineContents[offlineContent.fieldid][''] = CoreTextUtils.parseJSON(offlineContent.value);
|
offlineContents[offlineContent.fieldid][''] = CoreTextUtils.parseJSON(offlineContent.value, '');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -632,7 +632,7 @@ export class AddonModDataHelperProvider {
|
||||||
const folderPath = await AddonModDataOffline.getEntryFieldFolder(dataId, entryId, fieldId, siteId);
|
const folderPath = await AddonModDataOffline.getEntryFieldFolder(dataId, entryId, fieldId, siteId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return CoreFileUploader.getStoredFiles(folderPath);
|
return await CoreFileUploader.getStoredFiles(folderPath);
|
||||||
} catch {
|
} catch {
|
||||||
// Ignore not found files.
|
// Ignore not found files.
|
||||||
return [];
|
return [];
|
||||||
|
|
|
@ -88,9 +88,9 @@ export class AddonModDataOfflineProvider {
|
||||||
const promises: Promise<void>[] = [];
|
const promises: Promise<void>[] = [];
|
||||||
|
|
||||||
entry.fields.forEach((field) => {
|
entry.fields.forEach((field) => {
|
||||||
const value = CoreTextUtils.parseJSON<CoreFileUploaderStoreFilesResult>(field.value);
|
const value = CoreTextUtils.parseJSON<CoreFileUploaderStoreFilesResult | null>(field.value, null);
|
||||||
|
|
||||||
if (!value.offline) {
|
if (!value || !value.offline) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -345,8 +345,8 @@ export class AddonModDataSyncProvider extends CoreCourseActivitySyncBaseProvider
|
||||||
try {
|
try {
|
||||||
await Promise.all(editAction.fields.map(async (field) => {
|
await Promise.all(editAction.fields.map(async (field) => {
|
||||||
// Upload Files if asked.
|
// Upload Files if asked.
|
||||||
const value = CoreTextUtils.parseJSON<CoreFileUploaderStoreFilesResult>(field.value || '');
|
const value = CoreTextUtils.parseJSON<CoreFileUploaderStoreFilesResult | null>(field.value || '', null);
|
||||||
if (value.online || value.offline) {
|
if (value && (value.online || value.offline)) {
|
||||||
let files: CoreFileEntry[] = value.online || [];
|
let files: CoreFileEntry[] = value.online || [];
|
||||||
|
|
||||||
const offlineFiles = value.offline
|
const offlineFiles = value.offline
|
||||||
|
|
|
@ -277,7 +277,10 @@ export class CoreUtilsProvider {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(source)) {
|
if (this.valueIsFileEntry(source)) {
|
||||||
|
// Don't clone FileEntry. It has a lot of depth and they shouldn't be modified.
|
||||||
|
return source;
|
||||||
|
} else if (Array.isArray(source)) {
|
||||||
// Clone the array and all the entries.
|
// Clone the array and all the entries.
|
||||||
const newArray = [] as unknown as T;
|
const newArray = [] as unknown as T;
|
||||||
for (let i = 0; i < source.length; i++) {
|
for (let i = 0; i < source.length; i++) {
|
||||||
|
@ -750,6 +753,18 @@ export class CoreUtilsProvider {
|
||||||
return 'isFile' in file;
|
return 'isFile' in file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an unknown value is a FileEntry.
|
||||||
|
*
|
||||||
|
* @param value Value to check.
|
||||||
|
* @return Type guard indicating if the file is a FileEntry.
|
||||||
|
*/
|
||||||
|
valueIsFileEntry(file: unknown): file is FileEntry {
|
||||||
|
// We cannot use instanceof because FileEntry is a type. Check some of the properties.
|
||||||
|
return !!(file && typeof file == 'object' && 'isFile' in file && 'filesystem' in file &&
|
||||||
|
'toInternalURL' in file && 'copyTo' in file);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a value is an object.
|
* Check if a value is an object.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue