MOBILE-4653 utils: Move object and array related utils functions
parent
453a2bd8c2
commit
96f3be2ff1
|
@ -19,7 +19,7 @@ import { CoreBlockBaseComponent } from '@features/block/classes/base-block-compo
|
|||
import { CoreSites } from '@services/sites';
|
||||
import { ContextLevel, CoreConstants } from '@/core/constants';
|
||||
import { Translate } from '@singletons';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreCourseHelper } from '@features/course/services/course-helper';
|
||||
import { CoreUrl } from '@singletons/url';
|
||||
|
@ -106,7 +106,7 @@ export class AddonBlockActivityModulesComponent extends CoreBlockBaseComponent i
|
|||
});
|
||||
|
||||
// Sort the modnames alphabetically.
|
||||
modFullNames = CoreUtils.sortValues(modFullNames);
|
||||
modFullNames = CoreObject.sortValues(modFullNames);
|
||||
for (const modName in modFullNames) {
|
||||
const iconModName = modName === 'resources' ? 'page' : modName;
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import { CoreFileEntry, CoreFileHelper } from '@services/file-helper';
|
|||
import { CoreNetwork } from '@services/network';
|
||||
import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites';
|
||||
import { CoreTimeUtils } from '@services/utils/time';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreStatusWithWarningsWSResponse, CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { AddonBlogOffline, AddonBlogOfflineEntry } from './blog-offline';
|
||||
|
@ -63,7 +63,7 @@ export class AddonBlogProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
getEntriesCacheKey(filter: AddonBlogFilter = {}): string {
|
||||
return ROOT_CACHE_KEY + CoreUtils.sortAndStringify(filter);
|
||||
return ROOT_CACHE_KEY + CoreObject.sortAndStringify(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,7 +77,7 @@ export class AddonBlogProvider {
|
|||
const site = await CoreSites.getSite(options?.siteId);
|
||||
|
||||
const data: CoreBlogGetEntriesWSParams = {
|
||||
filters: CoreUtils.objectToArrayOfObjects(filter, 'name', 'value'),
|
||||
filters: CoreObject.toArrayOfObjects(filter, 'name', 'value'),
|
||||
page: options?.page ?? 0,
|
||||
perpage: AddonBlogProvider.ENTRIES_PER_PAGE,
|
||||
};
|
||||
|
@ -290,7 +290,7 @@ export class AddonBlogProvider {
|
|||
const site = await CoreSites.getSite(siteId);
|
||||
|
||||
const data: AddonBlogViewEntriesWSParams = {
|
||||
filters: CoreUtils.objectToArrayOfObjects(filter, 'name', 'value'),
|
||||
filters: CoreObject.toArrayOfObjects(filter, 'name', 'value'),
|
||||
};
|
||||
|
||||
return site.write('core_blog_view_entries', data);
|
||||
|
|
|
@ -29,7 +29,7 @@ import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
|||
import { CoreSites } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreTimeUtils } from '@services/utils/time';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import {
|
||||
AddonCalendar,
|
||||
AddonCalendarWeek,
|
||||
|
@ -464,7 +464,7 @@ class AddonCalendarMonthSlidesItemsManagerSource extends CoreSwipeSlidesDynamicI
|
|||
const categories = await CoreCourses.getCategories(0, true);
|
||||
|
||||
// Index categories by ID.
|
||||
this.categories = CoreUtils.arrayToObject(categories, 'id');
|
||||
this.categories = CoreArray.toObject(categories, 'id');
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { CoreEnrolledCourseData } from '@features/courses/services/courses';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { ModalController } from '@singletons';
|
||||
import { CoreEvents } from '@singletons/events';
|
||||
import { AddonCalendarFilter } from '@addons/calendar/services/calendar-helper';
|
||||
|
@ -54,7 +54,7 @@ export class AddonCalendarFilterComponent implements OnInit {
|
|||
sortedCourses: CoreEnrolledCourseData[] = [];
|
||||
|
||||
constructor() {
|
||||
CoreUtils.enumKeys(AddonCalendarEventType).forEach((name) => {
|
||||
CoreObject.enumKeys(AddonCalendarEventType).forEach((name) => {
|
||||
const value = AddonCalendarEventType[name];
|
||||
this.typeIcons[value] = AddonCalendarEventIcons[name];
|
||||
this.types.push(value);
|
||||
|
|
|
@ -33,7 +33,7 @@ import { NgZone, Translate } from '@singletons';
|
|||
import { CoreNavigator } from '@services/navigator';
|
||||
import { Params } from '@angular/router';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { CoreConstants } from '@/core/constants';
|
||||
import { CoreSwipeSlidesDynamicItemsManager } from '@classes/items-management/swipe-slides-dynamic-items-manager';
|
||||
import { CoreSwipeSlidesComponent } from '@components/swipe-slides/swipe-slides';
|
||||
|
@ -58,6 +58,7 @@ import {
|
|||
ADDON_CALENDAR_UNDELETED_EVENT_EVENT,
|
||||
AddonCalendarEventType,
|
||||
} from '@addons/calendar/constants';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
/**
|
||||
* Page that displays the calendar events for a certain day.
|
||||
|
@ -221,7 +222,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy {
|
|||
ngOnInit(): void {
|
||||
const types: string[] = [];
|
||||
|
||||
CoreUtils.enumKeys(AddonCalendarEventType).forEach((name) => {
|
||||
CoreObject.enumKeys(AddonCalendarEventType).forEach((name) => {
|
||||
const value = AddonCalendarEventType[name];
|
||||
this.filter[name] = CoreNavigator.getRouteBooleanParam(name) ?? true;
|
||||
types.push(value);
|
||||
|
@ -606,7 +607,7 @@ class AddonCalendarDaySlidesItemsManagerSource extends CoreSwipeSlidesDynamicIte
|
|||
const categories = await CoreCourses.getCategories(0, true);
|
||||
|
||||
// Index categories by ID.
|
||||
this.categories = CoreUtils.arrayToObject(categories, 'id');
|
||||
this.categories = CoreArray.toObject(categories, 'id');
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import {
|
|||
AddonCalendarWeekDay,
|
||||
} from './calendar';
|
||||
import { CoreConfig } from '@services/config';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreCourse } from '@features/course/services/course';
|
||||
import { ContextLevel, CoreConstants } from '@/core/constants';
|
||||
import moment from 'moment-timezone';
|
||||
|
@ -61,7 +61,7 @@ export class AddonCalendarHelperProvider {
|
|||
*/
|
||||
getEventIcon(eventType: AddonCalendarEventType | string): string {
|
||||
if (this.eventTypeIcons.length == 0) {
|
||||
CoreUtils.enumKeys(AddonCalendarEventType).forEach((name) => {
|
||||
CoreObject.enumKeys(AddonCalendarEventType).forEach((name) => {
|
||||
const value = AddonCalendarEventType[name];
|
||||
this.eventTypeIcons[value] = AddonCalendarEventIcons[name];
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { SQLiteDBRecordValues } from '@classes/sqlitedb';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { AddonCalendarSubmitCreateUpdateFormDataWSParams } from './calendar';
|
||||
import {
|
||||
|
@ -62,7 +62,7 @@ export class AddonCalendarOfflineProvider {
|
|||
|
||||
const result = await Promise.all(promises);
|
||||
|
||||
return CoreUtils.mergeArraysWithoutDuplicates(result[0], result[1]);
|
||||
return CoreArray.mergeWithoutDuplicates(result[0], result[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,7 +19,7 @@ import { CoreNetwork } from '@services/network';
|
|||
import { CoreText } from '@singletons/text';
|
||||
import { CoreTimeUtils } from '@services/utils/time';
|
||||
import { CoreUrl } from '@singletons/url';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreGroups } from '@services/groups';
|
||||
import { CoreLocalNotifications } from '@services/local-notifications';
|
||||
import { CoreConfig } from '@services/config';
|
||||
|
@ -1578,7 +1578,7 @@ export class AddonCalendarProvider {
|
|||
}
|
||||
|
||||
const params: AddonCalendarSubmitCreateUpdateFormWSParams = {
|
||||
formdata: CoreUtils.objectToGetParams(formData),
|
||||
formdata: CoreObject.toGetParams(formData),
|
||||
};
|
||||
const result =
|
||||
await site.write<AddonCalendarSubmitCreateUpdateFormWSResponse>('core_calendar_submit_create_update_form', params);
|
||||
|
|
|
@ -27,7 +27,7 @@ import {
|
|||
AddonModAssignSubmissionStatusValues,
|
||||
} from './assign';
|
||||
import { AddonModAssignOffline } from './assign-offline';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreFile } from '@services/file';
|
||||
import { CoreCourseCommonModWSOptions } from '@features/course/services/course';
|
||||
import { CoreGroups } from '@services/groups';
|
||||
|
@ -314,7 +314,7 @@ export class AddonModAssignHelperProvider {
|
|||
|
||||
await Promise.all(promises);
|
||||
|
||||
return CoreUtils.objectToArray(participantsIndexed);
|
||||
return CoreObject.toArray(participantsIndexed);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,7 +23,7 @@ import { CoreSites } from '@services/sites';
|
|||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreText } from '@singletons/text';
|
||||
import { CoreTimeUtils } from '@services/utils/time';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { Translate } from '@singletons';
|
||||
import {
|
||||
AddonModBBB,
|
||||
|
@ -146,7 +146,7 @@ export class AddonModBBBIndexComponent extends CoreCourseModuleMainActivityCompo
|
|||
const recordingsTable = await AddonModBBB.getRecordings(this.bbb.id, this.groupId, {
|
||||
cmId: this.module.id,
|
||||
});
|
||||
const columns = CoreUtils.arrayToObject(recordingsTable.columns, 'key');
|
||||
const columns = CoreArray.toObject(recordingsTable.columns, 'key');
|
||||
|
||||
this.recordings = recordingsTable.parsedData.map(recordingData => {
|
||||
const details: RecordingDetail[] = [];
|
||||
|
|
|
@ -20,7 +20,7 @@ import { CoreCourseCommonModWSOptions } from '@features/course/services/course';
|
|||
import { CoreCourseLogHelper } from '@features/course/services/log-helper';
|
||||
import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites';
|
||||
import { CoreText } from '@singletons/text';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws';
|
||||
import { makeSingleton, Translate } from '@singletons';
|
||||
import { ADDON_MOD_BBB_COMPONENT } from '../constants';
|
||||
|
@ -182,7 +182,7 @@ export class AddonModBBBService {
|
|||
|
||||
return {
|
||||
...meetingInfo,
|
||||
features: meetingInfo.features ? CoreUtils.objectToKeyValueMap(meetingInfo.features, 'name', 'isenabled') : undefined,
|
||||
features: meetingInfo.features ? CoreObject.toKeyValueMap(meetingInfo.features, 'name', 'isenabled') : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ import { CoreNavigator } from '@services/navigator';
|
|||
import { CoreSites } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreTimeUtils } from '@services/utils/time';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||
import {
|
||||
AddonModData,
|
||||
|
@ -53,6 +53,7 @@ import {
|
|||
} from '../../constants';
|
||||
import { CoreModals } from '@services/modals';
|
||||
import { CorePromiseUtils } from '@singletons/promise-utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
const contentToken = '<!-- CORE-DATABASE-CONTENT-GOES-HERE -->';
|
||||
|
||||
|
@ -269,8 +270,8 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
const fields = await AddonModData.getFields(this.database.id, { cmId: this.module.id });
|
||||
this.search.advanced = [];
|
||||
|
||||
this.fields = CoreUtils.arrayToObject(fields, 'id');
|
||||
this.fieldsArray = CoreUtils.objectToArray(this.fields);
|
||||
this.fields = CoreArray.toObject(fields, 'id');
|
||||
this.fieldsArray = CoreObject.toArray(this.fields);
|
||||
if (this.fieldsArray.length == 0) {
|
||||
canSearch = false;
|
||||
canAdd = false;
|
||||
|
|
|
@ -18,7 +18,7 @@ import { CoreTag } from '@features/tag/services/tag';
|
|||
import { CoreSites } from '@services/sites';
|
||||
import { CoreFormFields, CoreForms } from '@singletons/form';
|
||||
import { CoreText } from '@singletons/text';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { ModalController } from '@singletons';
|
||||
import {
|
||||
AddonModDataField,
|
||||
|
@ -89,7 +89,7 @@ export class AddonModDataSearchModalComponent implements OnInit {
|
|||
this.searchForm.addControl('firstname', this.fb.control(this.advancedIndexed['firstname'] || ''));
|
||||
this.searchForm.addControl('lastname', this.fb.control(this.advancedIndexed['lastname'] || ''));
|
||||
|
||||
this.fieldsArray = CoreUtils.objectToArray(this.fields);
|
||||
this.fieldsArray = CoreObject.toArray(this.fields);
|
||||
this.advancedSearch = this.renderAdvancedSearchFields();
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
|
|||
import { ADDON_MOD_DATA_COMPONENT, ADDON_MOD_DATA_ENTRY_CHANGED, AddonModDataTemplateType } from '../../constants';
|
||||
import { CoreLoadings } from '@services/loadings';
|
||||
import { CoreWSError } from '@classes/errors/wserror';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
|
||||
/**
|
||||
* Page that displays the view edit page.
|
||||
|
@ -180,7 +181,7 @@ export class AddonModDataEditPage implements OnInit {
|
|||
this.cssClass = 'addon-data-entries-' + this.database.id;
|
||||
|
||||
this.fieldsArray = await AddonModData.getFields(this.database.id, { cmId: this.moduleId });
|
||||
this.fields = CoreUtils.arrayToObject(this.fieldsArray, 'id');
|
||||
this.fields = CoreArray.toObject(this.fieldsArray, 'id');
|
||||
|
||||
const entry = await AddonModDataHelper.fetchEntry(this.database, this.fieldsArray, this.entryId || 0);
|
||||
this.entry = entry.entry;
|
||||
|
|
|
@ -22,7 +22,7 @@ import { CoreGroups, CoreGroupInfo } from '@services/groups';
|
|||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||
import { AddonModDataComponentsCompileModule } from '../../components/components-compile.module';
|
||||
import {
|
||||
|
@ -183,7 +183,7 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy {
|
|||
this.title = this.database.name || this.title;
|
||||
|
||||
this.fieldsArray = await AddonModData.getFields(this.database.id, { cmId: this.moduleId });
|
||||
this.fields = CoreUtils.arrayToObject(this.fieldsArray, 'id');
|
||||
this.fields = CoreArray.toObject(this.fieldsArray, 'id');
|
||||
|
||||
await this.setEntryFromOffset();
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ import { CoreFileEntry } from '@services/file-helper';
|
|||
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
|
||||
import { CoreSync, CoreSyncResult } from '@services/sync';
|
||||
import { CoreErrorHelper } from '@services/error-helper';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { Translate, makeSingleton } from '@singletons';
|
||||
import { CoreEvents } from '@singletons/events';
|
||||
import { AddonModData, AddonModDataData } from './data';
|
||||
|
@ -206,7 +206,7 @@ export class AddonModDataSyncProvider extends CoreCourseActivitySyncBaseProvider
|
|||
offlineEntries[entry.entryid].push(entry);
|
||||
});
|
||||
|
||||
const promises = CoreUtils.objectToArray(offlineEntries).map((entryActions) =>
|
||||
const promises = CoreObject.toArray(offlineEntries).map((entryActions) =>
|
||||
this.syncEntry(database, entryActions, result, siteId));
|
||||
|
||||
await Promise.all(promises);
|
||||
|
|
|
@ -22,7 +22,7 @@ import { CoreNetwork } from '@services/network';
|
|||
import { CoreFileEntry } from '@services/file-helper';
|
||||
import { CoreFilepool } from '@services/filepool';
|
||||
import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@services/sites';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws';
|
||||
import { makeSingleton, Translate } from '@singletons';
|
||||
import { AddonModDataFieldsDelegate } from './data-fields-delegate';
|
||||
|
@ -251,7 +251,7 @@ export class AddonModDataProvider {
|
|||
*/
|
||||
protected checkFields(fields: AddonModDataField[], contents: AddonModDataSubfieldData[]): AddonModDataFieldNotification[] {
|
||||
const notifications: AddonModDataFieldNotification[] = [];
|
||||
const contentsIndexed = CoreUtils.arrayToObjectMultiple(contents, 'fieldid');
|
||||
const contentsIndexed = CoreArray.toObjectMultiple(contents, 'fieldid');
|
||||
|
||||
// App is offline, check required fields.
|
||||
fields.forEach((field) => {
|
||||
|
@ -741,7 +741,7 @@ export class AddonModDataProvider {
|
|||
*/
|
||||
protected formatEntryContents(entry: AddonModDataEntryWS): AddonModDataEntry {
|
||||
return Object.assign(entry, {
|
||||
contents: CoreUtils.arrayToObject(entry.contents, 'fieldid'),
|
||||
contents: CoreArray.toObject(entry.contents, 'fieldid'),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import { CoreFilepool } from '@services/filepool';
|
|||
import { CoreGroup, CoreGroups } from '@services/groups';
|
||||
import { CoreSitesCommonWSOptions, CoreSites, CoreSitesReadingStrategy } from '@services/sites';
|
||||
import { CoreTimeUtils } from '@services/utils/time';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreWSFile } from '@services/ws';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { AddonModDataEntry, AddonModData, AddonModDataData } from '../data';
|
||||
|
@ -63,7 +63,7 @@ export class AddonModDataPrefetchHandlerLazyService extends AddonModDataPrefetch
|
|||
});
|
||||
});
|
||||
|
||||
return CoreUtils.objectToArray(uniqueEntries);
|
||||
return CoreObject.toArray(uniqueEntries);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,7 +133,7 @@ export class AddonModDataPrefetchHandlerLazyService extends AddonModDataPrefetch
|
|||
let files: CoreWSFile[] = [];
|
||||
|
||||
entries.forEach((entry) => {
|
||||
CoreUtils.objectToArray(entry.contents).forEach((content) => {
|
||||
CoreObject.toArray(entry.contents).forEach((content) => {
|
||||
files = files.concat(<CoreWSFile[]>content.files);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -46,6 +46,7 @@ import { CoreLoadings } from '@services/loadings';
|
|||
import { CoreError } from '@classes/errors/error';
|
||||
import { CorePromiseUtils } from '@singletons/promise-utils';
|
||||
import { CoreWSError } from '@classes/errors/wserror';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
/**
|
||||
* Page that displays feedback form.
|
||||
|
@ -158,7 +159,7 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave {
|
|||
|
||||
if (this.items && !this.completed && this.originalData) {
|
||||
// Form submitted. Check if there is any change.
|
||||
if (!CoreUtils.basicLeftCompare(responses, this.originalData, 3)) {
|
||||
if (!CoreObject.basicLeftCompare(responses, this.originalData, 3)) {
|
||||
await CoreDomUtils.showConfirm(Translate.instant('core.confirmcanceledit'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import { CoreCourseLogHelper } from '@features/course/services/log-helper';
|
|||
import { CoreNetwork } from '@services/network';
|
||||
import { CoreFilepool } from '@services/filepool';
|
||||
import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@services/sites';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreWSExternalFile, CoreWSExternalWarning, CoreWSStoredFile } from '@services/ws';
|
||||
import { makeSingleton, Translate } from '@singletons';
|
||||
import { AddonModFeedbackOffline } from './feedback-offline';
|
||||
|
@ -170,7 +170,7 @@ export class AddonModFeedbackProvider {
|
|||
|
||||
// Merge all values into one array.
|
||||
const offlineValuesArray = offlineResponses.reduce((array, entry) => {
|
||||
const responses = <OfflineResponsesArray> CoreUtils.objectToArrayOfObjects(entry.responses, 'id', 'value');
|
||||
const responses = <OfflineResponsesArray> CoreObject.toArrayOfObjects(entry.responses, 'id', 'value');
|
||||
|
||||
return array.concat(responses);
|
||||
}, <OfflineResponsesArray> []).map((valueEntry) => {
|
||||
|
@ -1228,7 +1228,7 @@ export class AddonModFeedbackProvider {
|
|||
const params: AddonModFeedbackProcessPageWSParams = {
|
||||
feedbackid: feedbackId,
|
||||
page: page,
|
||||
responses: CoreUtils.objectToArrayOfObjects(responses, 'name', 'value'),
|
||||
responses: CoreObject.toArrayOfObjects(responses, 'name', 'value'),
|
||||
goprevious: goPrevious,
|
||||
};
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ import { CoreCourseContentsPage } from '@features/course/pages/contents/contents
|
|||
import { CoreToasts } from '@services/toasts';
|
||||
import { CoreLoadings } from '@services/loadings';
|
||||
import { CorePromiseUtils } from '@singletons/promise-utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
type SortType = 'flat-newest' | 'flat-oldest' | 'nested';
|
||||
|
||||
|
@ -463,7 +464,7 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
|||
await Promise.all(convertPromises);
|
||||
|
||||
// Convert back to array.
|
||||
onlinePosts = CoreUtils.objectToArray(onlinePostsMap);
|
||||
onlinePosts = CoreObject.toArray(onlinePostsMap);
|
||||
|
||||
let posts = offlineReplies.concat(onlinePosts);
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ import {
|
|||
import { CoreCacheUpdateFrequency } from '@/core/constants';
|
||||
import { CorePromiseUtils } from '@singletons/promise-utils';
|
||||
import { CoreWSError } from '@classes/errors/wserror';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
declare module '@singletons/events' {
|
||||
|
||||
|
@ -221,7 +222,7 @@ export class AddonModForumProvider {
|
|||
message: message,
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
options: CoreUtils.objectToArrayOfObjects<AddonModForumAddDiscussionWSOptionsArray[0], AddonModForumAddDiscussionWSOptionsObject>(
|
||||
options: CoreObject.toArrayOfObjects<AddonModForumAddDiscussionWSOptionsArray[0], AddonModForumAddDiscussionWSOptionsObject>(
|
||||
options || {},
|
||||
'name',
|
||||
'value',
|
||||
|
@ -1147,7 +1148,7 @@ export class AddonModForumProvider {
|
|||
subject: subject,
|
||||
message: message,
|
||||
|
||||
options: CoreUtils.objectToArrayOfObjects<
|
||||
options: CoreObject.toArrayOfObjects<
|
||||
AddonModForumAddDiscussionPostWSOptionsArray[0],
|
||||
AddonModForumAddDiscussionPostWSOptionsObject
|
||||
>(
|
||||
|
@ -1277,7 +1278,7 @@ export class AddonModForumProvider {
|
|||
}
|
||||
});
|
||||
|
||||
CoreUser.storeUsers(CoreUtils.objectToArray(users));
|
||||
CoreUser.storeUsers(CoreObject.toArray(users));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1332,7 +1333,7 @@ export class AddonModForumProvider {
|
|||
subject: subject,
|
||||
message: message,
|
||||
|
||||
options: CoreUtils.objectToArrayOfObjects<
|
||||
options: CoreObject.toArrayOfObjects<
|
||||
AddonModForumUpdateDiscussionPostWSOptionsArray[0],
|
||||
AddonModForumUpdateDiscussionPostWSOptionsObject
|
||||
>(
|
||||
|
|
|
@ -22,7 +22,7 @@ import { CoreRatingInfo } from '@features/rating/services/rating';
|
|||
import { CoreTagItem } from '@features/tag/services/tag';
|
||||
import { CoreNetwork } from '@services/network';
|
||||
import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@services/sites';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws';
|
||||
import { makeSingleton, Translate } from '@singletons';
|
||||
import { CoreEvents } from '@singletons/events';
|
||||
|
@ -911,7 +911,7 @@ export class AddonModGlossaryProvider {
|
|||
concept: concept,
|
||||
definition: definition,
|
||||
definitionformat: 1,
|
||||
options: CoreUtils.objectToArrayOfObjects(options || {}, 'name', 'value'),
|
||||
options: CoreObject.toArrayOfObjects(options || {}, 'name', 'value'),
|
||||
};
|
||||
|
||||
if (attachId) {
|
||||
|
@ -955,7 +955,7 @@ export class AddonModGlossaryProvider {
|
|||
concept: concept,
|
||||
definition: definition,
|
||||
definitionformat: 1,
|
||||
options: CoreUtils.objectToArrayOfObjects(options || {}, 'name', 'value'),
|
||||
options: CoreObject.toArrayOfObjects(options || {}, 'name', 'value'),
|
||||
};
|
||||
|
||||
if (attachId) {
|
||||
|
|
|
@ -24,7 +24,7 @@ import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@
|
|||
import { CoreSync } from '@services/sync';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreUrl } from '@singletons/url';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreWSExternalFile } from '@services/ws';
|
||||
import { ModalController, Translate } from '@singletons';
|
||||
import { CoreEvents } from '@singletons/events';
|
||||
|
@ -171,7 +171,7 @@ export class AddonModLessonPlayerPage implements OnInit, OnDestroy, CanLeave {
|
|||
|
||||
if (this.question && !this.eolData && !this.processData && this.originalData) {
|
||||
// Question shown. Check if there is any change.
|
||||
if (!CoreUtils.basicLeftCompare(this.questionForm.getRawValue(), this.originalData, 3)) {
|
||||
if (!CoreObject.basicLeftCompare(this.questionForm.getRawValue(), this.originalData, 3)) {
|
||||
await CoreDomUtils.showConfirm(Translate.instant('core.confirmcanceledit'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import { CoreSites } from '@services/sites';
|
|||
import { CoreFormFields } from '@singletons/form';
|
||||
import { CoreText } from '@singletons/text';
|
||||
import { CoreTimeUtils } from '@services/utils/time';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import {
|
||||
AddonModLessonPageAttemptDBRecord,
|
||||
|
@ -152,7 +152,7 @@ export class AddonModLessonOfflineProvider {
|
|||
this.getLessonsFromEntries(lessons, pageAttempts || []);
|
||||
this.getLessonsFromEntries(lessons, retakes || []);
|
||||
|
||||
return CoreUtils.objectToArray(lessons);
|
||||
return CoreObject.toArray(lessons);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,6 +37,8 @@ import {
|
|||
import { CoreGradeType } from '@features/grades/constants';
|
||||
import { CoreCacheUpdateFrequency } from '@/core/constants';
|
||||
import { CorePromiseUtils } from '@singletons/promise-utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
|
||||
declare module '@singletons/events' {
|
||||
|
||||
|
@ -286,7 +288,7 @@ export class AddonModLessonProvider {
|
|||
const validPages = {};
|
||||
let pageId = accessInfo.firstpageid;
|
||||
|
||||
viewedPagesIds = CoreUtils.mergeArraysWithoutDuplicates(viewedPagesIds, viewedContentPagesIds);
|
||||
viewedPagesIds = CoreArray.mergeWithoutDuplicates(viewedPagesIds, viewedContentPagesIds);
|
||||
|
||||
// Filter out the following pages:
|
||||
// - End of Cluster
|
||||
|
@ -398,11 +400,11 @@ export class AddonModLessonProvider {
|
|||
// The name was changed to "answer_editor" in 3.7. Before it was just "answer". Support both cases.
|
||||
if (data['answer_editor[text]'] !== undefined) {
|
||||
studentAnswer = data['answer_editor[text]'];
|
||||
} else if (typeof data.answer_editor == 'object') {
|
||||
} else if (typeof data.answer_editor === 'object') {
|
||||
studentAnswer = (<{text: string}> data.answer_editor).text;
|
||||
} else if (data['answer[text]'] !== undefined) {
|
||||
studentAnswer = data['answer[text]'];
|
||||
} else if (typeof data.answer == 'object') {
|
||||
} else if (typeof data.answer === 'object') {
|
||||
studentAnswer = (<{text: string}> data.answer).text;
|
||||
} else {
|
||||
studentAnswer = data.answer;
|
||||
|
@ -3087,7 +3089,7 @@ export class AddonModLessonProvider {
|
|||
const params: AddonModLessonProcessPageWSParams = {
|
||||
lessonid: lessonId,
|
||||
pageid: pageId,
|
||||
data: CoreUtils.objectToArrayOfObjects<ProcessPageData>(data, 'name', 'value', true),
|
||||
data: CoreObject.toArrayOfObjects<ProcessPageData>(data, 'name', 'value', true),
|
||||
review: !!options.review,
|
||||
};
|
||||
|
||||
|
|
|
@ -53,6 +53,8 @@ import {
|
|||
} from '../constants';
|
||||
import { CoreIonicColorNames } from '@singletons/colors';
|
||||
import { CoreCacheUpdateFrequency } from '@/core/constants';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
|
||||
declare module '@singletons/events' {
|
||||
|
||||
|
@ -227,7 +229,7 @@ export class AddonModQuizProvider {
|
|||
const params: AddonModQuizGetAttemptDataWSParams = {
|
||||
attemptid: attemptId,
|
||||
page: page,
|
||||
preflightdata: CoreUtils.objectToArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
preflightdata: CoreObject.toArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
preflightData,
|
||||
'name',
|
||||
'value',
|
||||
|
@ -550,7 +552,7 @@ export class AddonModQuizProvider {
|
|||
|
||||
const params: AddonModQuizGetAttemptSummaryWSParams = {
|
||||
attemptid: attemptId,
|
||||
preflightdata: CoreUtils.objectToArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
preflightdata: CoreObject.toArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
preflightData,
|
||||
'name',
|
||||
'value',
|
||||
|
@ -629,8 +631,8 @@ export class AddonModQuizProvider {
|
|||
|
||||
// Convert the arrays to objects with name -> value.
|
||||
return {
|
||||
someoptions: <Record<string, number>> CoreUtils.objectToKeyValueMap(response.someoptions, 'name', 'value'),
|
||||
alloptions: <Record<string, number>> CoreUtils.objectToKeyValueMap(response.alloptions, 'name', 'value'),
|
||||
someoptions: <Record<string, number>> CoreObject.toKeyValueMap(response.someoptions, 'name', 'value'),
|
||||
alloptions: <Record<string, number>> CoreObject.toKeyValueMap(response.alloptions, 'name', 'value'),
|
||||
warnings: response.warnings,
|
||||
};
|
||||
}
|
||||
|
@ -1640,7 +1642,7 @@ export class AddonModQuizProvider {
|
|||
const params: AddonModQuizViewAttemptWSParams = {
|
||||
attemptid: attemptId,
|
||||
page: page,
|
||||
preflightdata: CoreUtils.objectToArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
preflightdata: CoreObject.toArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
preflightData,
|
||||
'name',
|
||||
'value',
|
||||
|
@ -1695,7 +1697,7 @@ export class AddonModQuizProvider {
|
|||
): Promise<void> {
|
||||
const params: AddonModQuizViewAttemptSummaryWSParams = {
|
||||
attemptid: attemptId,
|
||||
preflightdata: CoreUtils.objectToArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
preflightdata: CoreObject.toArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
preflightData,
|
||||
'name',
|
||||
'value',
|
||||
|
@ -1785,10 +1787,10 @@ export class AddonModQuizProvider {
|
|||
|
||||
const params: AddonModQuizProcessAttemptWSParams = {
|
||||
attemptid: attemptId,
|
||||
data: CoreUtils.objectToArrayOfObjects(data, 'name', 'value'),
|
||||
data: CoreObject.toArrayOfObjects(data, 'name', 'value'),
|
||||
finishattempt: !!finish,
|
||||
timeup: !!timeUp,
|
||||
preflightdata: CoreUtils.objectToArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
preflightdata: CoreObject.toArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
preflightData,
|
||||
'name',
|
||||
'value',
|
||||
|
@ -1834,7 +1836,7 @@ export class AddonModQuizProvider {
|
|||
});
|
||||
|
||||
// Convert the question array to an object.
|
||||
const questions = CoreUtils.arrayToObject(questionsArray, 'slot');
|
||||
const questions = CoreArray.toObject(questionsArray, 'slot');
|
||||
|
||||
return AddonModQuizOffline.processAttempt(quiz, attempt, questions, data, finish, siteId);
|
||||
}
|
||||
|
@ -1939,8 +1941,8 @@ export class AddonModQuizProvider {
|
|||
|
||||
const params: AddonModQuizSaveAttemptWSParams = {
|
||||
attemptid: attemptId,
|
||||
data: CoreUtils.objectToArrayOfObjects(data, 'name', 'value'),
|
||||
preflightdata: CoreUtils.objectToArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
data: CoreObject.toArrayOfObjects(data, 'name', 'value'),
|
||||
preflightdata: CoreObject.toArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
preflightData,
|
||||
'name',
|
||||
'value',
|
||||
|
@ -1995,7 +1997,7 @@ export class AddonModQuizProvider {
|
|||
|
||||
const params: AddonModQuizStartAttemptWSParams = {
|
||||
quizid: quizId,
|
||||
preflightdata: CoreUtils.objectToArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
preflightdata: CoreObject.toArrayOfObjects<AddonModQuizPreflightDataWSParam>(
|
||||
preflightData,
|
||||
'name',
|
||||
'value',
|
||||
|
|
|
@ -22,7 +22,7 @@ import { IonContent } from '@ionic/angular';
|
|||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreSync } from '@services/sync';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { Translate } from '@singletons';
|
||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||
import { AddonModScormPrefetchHandler } from '../../services/handlers/prefetch';
|
||||
|
@ -340,8 +340,8 @@ export class AddonModScormIndexComponent extends CoreCourseModuleMainActivityCom
|
|||
this.grade = AddonModScorm.calculateScormGrade(scorm, onlineAttempts);
|
||||
|
||||
// Add the attempts to the SCORM in array format in ASC order, and format the grades.
|
||||
this.onlineAttempts = CoreUtils.objectToArray(onlineAttempts);
|
||||
this.offlineAttempts = CoreUtils.objectToArray(offlineAttempts);
|
||||
this.onlineAttempts = CoreObject.toArray(onlineAttempts);
|
||||
this.offlineAttempts = CoreObject.toArray(offlineAttempts);
|
||||
this.onlineAttempts.sort((a, b) => a.num - b.num);
|
||||
this.offlineAttempts.sort((a, b) => a.num - b.num);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import { CoreSync } from '@services/sync';
|
|||
import { CoreText } from '@singletons/text';
|
||||
import { CoreTimeUtils } from '@services/utils/time';
|
||||
import { CoreUrl } from '@singletons/url';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreWS, CoreWSExternalFile, CoreWSExternalWarning, CoreWSFile, CoreWSPreSets } from '@services/ws';
|
||||
import { makeSingleton, Translate } from '@singletons';
|
||||
import { CoreEvents } from '@singletons/events';
|
||||
|
@ -808,12 +808,12 @@ export class AddonModScormProvider {
|
|||
response.data.forEach((sco) => {
|
||||
data[sco.scoid] = {
|
||||
scoid: sco.scoid,
|
||||
defaultdata: <Record<string, AddonModScormDataValue>> CoreUtils.objectToKeyValueMap(
|
||||
defaultdata: <Record<string, AddonModScormDataValue>> CoreObject.toKeyValueMap(
|
||||
sco.defaultdata,
|
||||
'element',
|
||||
'value',
|
||||
),
|
||||
userdata: <Record<string, AddonModScormDataValue>> CoreUtils.objectToKeyValueMap(sco.userdata, 'element', 'value'),
|
||||
userdata: <Record<string, AddonModScormDataValue>> CoreObject.toKeyValueMap(sco.userdata, 'element', 'value'),
|
||||
};
|
||||
|
||||
});
|
||||
|
@ -1114,7 +1114,7 @@ export class AddonModScormProvider {
|
|||
}
|
||||
|
||||
if (response.options) {
|
||||
const scormOptions = CoreUtils.objectToKeyValueMap(response.options, 'name', 'value');
|
||||
const scormOptions = CoreObject.toKeyValueMap(response.options, 'name', 'value');
|
||||
|
||||
if (scormOptions.scormstandard) {
|
||||
currentScorm.scormStandard = Number(scormOptions.scormstandard);
|
||||
|
|
|
@ -45,6 +45,7 @@ import { toBoolean } from '@/core/transforms/boolean';
|
|||
import { CoreLoadings } from '@services/loadings';
|
||||
import { CorePromiseUtils } from '@singletons/promise-utils';
|
||||
import { CoreWSError } from '@classes/errors/wserror';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
/**
|
||||
* Component that displays workshop assessment strategy form.
|
||||
|
@ -188,7 +189,7 @@ export class AddonModWorkshopAssessmentStrategyComponent implements OnInit, OnDe
|
|||
|
||||
// Override assessment plugins values.
|
||||
this.data.assessment.form.current = AddonModWorkshop.parseFields(
|
||||
CoreUtils.objectToArrayOfObjects(offlineData, 'name', 'value'),
|
||||
CoreObject.toArrayOfObjects(offlineData, 'name', 'value'),
|
||||
);
|
||||
|
||||
// Override offline files.
|
||||
|
|
|
@ -22,7 +22,7 @@ import { CoreGroupInfo, CoreGroups } from '@services/groups';
|
|||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CorePlatform } from '@services/platform';
|
||||
import { CoreModals } from '@services/modals';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||
import { Subscription } from 'rxjs';
|
||||
import {
|
||||
|
@ -405,7 +405,7 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
|
|||
const modalData = await CoreModals.openModal<boolean>({
|
||||
component: AddonModWorkshopPhaseInfoModalComponent,
|
||||
componentProps: {
|
||||
phases: CoreUtils.objectToArray(this.phases),
|
||||
phases: CoreObject.toArray(this.phases),
|
||||
workshopPhase: this.workshop.phase,
|
||||
externalUrl: this.module.url,
|
||||
showSubmit: this.showSubmit,
|
||||
|
|
|
@ -20,7 +20,7 @@ import { CoreUser } from '@features/user/services/user';
|
|||
import { CoreFilepool } from '@services/filepool';
|
||||
import { CoreGroup, CoreGroups } from '@services/groups';
|
||||
import { CoreSites, CoreSitesReadingStrategy, CoreSitesCommonWSOptions } from '@services/sites';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreWSExternalFile, CoreWSFile } from '@services/ws';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import {
|
||||
|
@ -248,7 +248,7 @@ export class AddonModWorkshopPrefetchHandlerLazyService extends AddonModWorkshop
|
|||
});
|
||||
});
|
||||
|
||||
return CoreUtils.objectToArray(uniqueGrades);
|
||||
return CoreObject.toArray(uniqueGrades);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,7 +20,7 @@ import { CoreGradesMenuItem } from '@features/grades/services/grades-helper';
|
|||
import { CoreNetwork } from '@services/network';
|
||||
import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@services/sites';
|
||||
import { CoreTextFormat, defaultTextFormat } from '@singletons/text';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { CoreStatusWithWarningsWSResponse, CoreWS, CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws';
|
||||
import { makeSingleton, Translate } from '@singletons';
|
||||
import { CoreFormFields } from '@singletons/form';
|
||||
|
@ -41,6 +41,7 @@ import {
|
|||
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
|
||||
import { CoreCacheUpdateFrequency } from '@/core/constants';
|
||||
import { CoreWSError } from '@classes/errors/wserror';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
declare module '@singletons/events' {
|
||||
|
||||
|
@ -366,7 +367,7 @@ export class AddonModWorkshopProvider {
|
|||
|
||||
const response = await site.read<AddonModWorkshopGetUserPlanWSResponse>('mod_workshop_get_user_plan', params, preSets);
|
||||
|
||||
return CoreUtils.arrayToObject(response.userplan.phases, 'code');
|
||||
return CoreArray.toObject(response.userplan.phases, 'code');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1052,7 +1053,7 @@ export class AddonModWorkshopProvider {
|
|||
warnings: response.warnings,
|
||||
fields: this.parseFields(response.fields),
|
||||
current: this.parseFields(response.current),
|
||||
options: CoreUtils.objectToKeyValueMap<string>(response.options, 'name', 'value'),
|
||||
options: CoreObject.toKeyValueMap<string>(response.options, 'name', 'value'),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1183,7 +1184,7 @@ export class AddonModWorkshopProvider {
|
|||
|
||||
const params: AddonModWorkshopUpdateAssessmentWSParams = {
|
||||
assessmentid: assessmentId,
|
||||
data: CoreUtils.objectToArrayOfObjects(inputData, 'name', 'value'),
|
||||
data: CoreObject.toArrayOfObjects(inputData, 'name', 'value'),
|
||||
};
|
||||
|
||||
const response = await site.write<AddonModWorkshopUpdateAssessmentWSResponse>('mod_workshop_update_assessment', params);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { AddonMessageOutputDelegate } from '@addons/messageoutput/services/messageoutput-delegate';
|
||||
import {
|
||||
|
@ -53,7 +53,7 @@ export class AddonNotificationsHelperProvider {
|
|||
|
||||
formattedPreferences.components.forEach((component) => {
|
||||
component.notifications.forEach((notification) => {
|
||||
notification.processorsByName = CoreUtils.arrayToObject(notification.processors, 'name');
|
||||
notification.processorsByName = CoreArray.toObject(notification.processors, 'name');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import { Injectable, Type } from '@angular/core';
|
|||
import { CoreQuestionQuestionParsed, CoreQuestionsAnswers } from '@features/question/services/question';
|
||||
import { CoreQuestionHandler } from '@features/question/services/question-delegate';
|
||||
import { convertTextToHTMLElement } from '@/core/utils/create-html-element';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { makeSingleton } from '@singletons';
|
||||
|
||||
/**
|
||||
|
@ -133,8 +133,8 @@ export class AddonQtypeCalculatedHandlerService implements CoreQuestionHandler {
|
|||
prevAnswers: CoreQuestionsAnswers,
|
||||
newAnswers: CoreQuestionsAnswers,
|
||||
): boolean {
|
||||
return CoreUtils.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, 'answer') &&
|
||||
CoreUtils.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, 'unit');
|
||||
return CoreObject.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, 'answer') &&
|
||||
CoreObject.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, 'unit');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,7 +24,7 @@ import { CoreFileSession } from '@services/file-session';
|
|||
import { CoreSites } from '@services/sites';
|
||||
import { convertTextToHTMLElement } from '@/core/utils/create-html-element';
|
||||
import { CoreText } from '@singletons/text';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreWSFile } from '@services/ws';
|
||||
import { makeSingleton, Translate } from '@singletons';
|
||||
import { CoreFileHelper } from '@services/file-helper';
|
||||
|
@ -267,7 +267,7 @@ export class AddonQtypeEssayHandlerService implements CoreQuestionHandler {
|
|||
|
||||
// First check the inline text.
|
||||
const answerIsEqual = allowedOptions.text ?
|
||||
CoreUtils.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, 'answer') : true;
|
||||
CoreObject.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, 'answer') : true;
|
||||
|
||||
if (!allowedOptions.attachments || !uploadFilesSupported || !answerIsEqual) {
|
||||
// No need to check attachments.
|
||||
|
|
|
@ -17,7 +17,7 @@ import { Injectable, Type } from '@angular/core';
|
|||
import { AddonModQuizMultichoiceQuestion } from '@features/question/classes/base-question-component';
|
||||
import { CoreQuestionQuestionParsed, CoreQuestionsAnswers } from '@features/question/services/question';
|
||||
import { CoreQuestionHandler } from '@features/question/services/question-delegate';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { makeSingleton } from '@singletons';
|
||||
|
||||
/**
|
||||
|
@ -120,7 +120,7 @@ export class AddonQtypeMultichoiceHandlerService implements CoreQuestionHandler
|
|||
for (const name in newAnswers) {
|
||||
if (name.indexOf('choice') !== -1) {
|
||||
isSingle = false;
|
||||
if (!CoreUtils.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, name)) {
|
||||
if (!CoreObject.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, name)) {
|
||||
isMultiSame = false;
|
||||
break;
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ export class AddonQtypeMultichoiceHandlerService implements CoreQuestionHandler
|
|||
* @returns Whether they're the same.
|
||||
*/
|
||||
isSameResponseSingle(prevAnswers: CoreQuestionsAnswers, newAnswers: CoreQuestionsAnswers): boolean {
|
||||
return CoreUtils.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, 'answer');
|
||||
return CoreObject.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, 'answer');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,7 +16,7 @@ import { Injectable, Type } from '@angular/core';
|
|||
|
||||
import { CoreQuestionQuestionParsed, CoreQuestionsAnswers } from '@features/question/services/question';
|
||||
import { CoreQuestionHandler } from '@features/question/services/question-delegate';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { makeSingleton } from '@singletons';
|
||||
|
||||
/**
|
||||
|
@ -72,7 +72,7 @@ export class AddonQtypeShortAnswerHandlerService implements CoreQuestionHandler
|
|||
prevAnswers: CoreQuestionsAnswers,
|
||||
newAnswers: CoreQuestionsAnswers,
|
||||
): boolean {
|
||||
return CoreUtils.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, 'answer');
|
||||
return CoreObject.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, 'answer');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import { Injectable, Type } from '@angular/core';
|
|||
|
||||
import { CoreQuestionHandler } from '@features/question/services/question-delegate';
|
||||
import { CoreQuestionQuestionParsed, CoreQuestionsAnswers } from '@features/question/services/question';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { AddonModQuizMultichoiceQuestion } from '@features/question/classes/base-question-component';
|
||||
import { makeSingleton } from '@singletons';
|
||||
|
||||
|
@ -74,7 +74,7 @@ export class AddonQtypeTrueFalseHandlerService implements CoreQuestionHandler {
|
|||
prevAnswers: CoreQuestionsAnswers,
|
||||
newAnswers: CoreQuestionsAnswers,
|
||||
): boolean {
|
||||
return CoreUtils.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, 'answer');
|
||||
return CoreObject.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, 'answer');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -66,7 +66,7 @@ export class CoreInterceptor implements HttpInterceptor {
|
|||
// Add the header and serialize the body if needed.
|
||||
const newReq = req.clone({
|
||||
headers: req.headers.set('Content-Type', 'application/x-www-form-urlencoded'),
|
||||
body: typeof req.body == 'object' && String(req.body) != '[object File]' ?
|
||||
body: typeof req.body === 'object' && String(req.body) != '[object File]' ?
|
||||
CoreInterceptor.serialize(req.body) : req.body,
|
||||
});
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ import { CoreSiteWSCacheRecord } from '@services/database/sites';
|
|||
import { CoreErrorLogs } from '@singletons/error-logs';
|
||||
import { CoreWait } from '@singletons/wait';
|
||||
import { CorePromiseUtils } from '@singletons/promise-utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
|
||||
/**
|
||||
* Class that represents a site (combination of site + user) where the user has authenticated but the site hasn't been validated
|
||||
|
@ -212,7 +214,7 @@ export class CoreAuthenticatedSite extends CoreUnauthenticatedSite {
|
|||
|
||||
// Index function by name to speed up wsAvailable method.
|
||||
if (infos?.functions) {
|
||||
infos.functionsByName = CoreUtils.arrayToObject(infos.functions, 'name');
|
||||
infos.functionsByName = CoreArray.toObject(infos.functions, 'name');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1020,7 +1022,7 @@ export class CoreAuthenticatedSite extends CoreUnauthenticatedSite {
|
|||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
protected getCacheId(method: string, data: any): string {
|
||||
return Md5.hashAsciiStr(method + ':' + CoreUtils.sortAndStringify(data));
|
||||
return Md5.hashAsciiStr(method + ':' + CoreObject.sortAndStringify(data));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
import { OnInit, Input, Component, Optional, Inject, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { CoreLogger } from '@singletons/logger';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { CoreText } from '@singletons/text';
|
||||
import { CoreCourseBlock } from '../../course/services/course';
|
||||
import { Params } from '@angular/router';
|
||||
|
@ -78,7 +78,7 @@ export abstract class CoreBlockBaseComponent implements OnInit, OnChanges, ICore
|
|||
config.value = CoreText.parseJSON(config.value);
|
||||
});
|
||||
|
||||
this.block.configsRecord = CoreUtils.arrayToObject(this.block.configs, 'name');
|
||||
this.block.configsRecord = CoreArray.toObject(this.block.configs, 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,6 +47,7 @@ import {
|
|||
CORE_COURSE_PROGRESS_UPDATED_EVENT,
|
||||
} from '@features/course/constants';
|
||||
import { CorePromiseUtils } from '@singletons/promise-utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
/**
|
||||
* Page that displays the contents of a course.
|
||||
|
@ -284,7 +285,7 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy, CoreRefreshCon
|
|||
|
||||
if ('courseformatoptions' in this.course && this.course.courseformatoptions) {
|
||||
// Already loaded.
|
||||
this.formatOptions = CoreUtils.objectToKeyValueMap(this.course.courseformatoptions, 'name', 'value');
|
||||
this.formatOptions = CoreObject.toKeyValueMap(this.course.courseformatoptions, 'name', 'value');
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -294,7 +295,7 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy, CoreRefreshCon
|
|||
course && Object.assign(this.course, course);
|
||||
|
||||
if (course?.courseformatoptions) {
|
||||
this.formatOptions = CoreUtils.objectToKeyValueMap(course.courseformatoptions, 'name', 'value');
|
||||
this.formatOptions = CoreObject.toKeyValueMap(course.courseformatoptions, 'name', 'value');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ import { CoreLogger } from '@singletons/logger';
|
|||
import { ApplicationInit, makeSingleton, Translate } from '@singletons';
|
||||
import { CoreFilepool } from '@services/filepool';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import {
|
||||
CoreCourseAnyCourseData,
|
||||
CoreCourseBasicData,
|
||||
|
@ -1088,7 +1088,7 @@ export class CoreCourseHelperProvider {
|
|||
|
||||
const totalOffline = offlineCompletions.length;
|
||||
let loaded = 0;
|
||||
const offlineCompletionsMap = CoreUtils.arrayToObject(offlineCompletions, 'cmid');
|
||||
const offlineCompletionsMap = CoreArray.toObject(offlineCompletions, 'cmid');
|
||||
|
||||
const loadSectionOfflineCompletion = (section: CoreCourseWSSection): void => {
|
||||
if (!section.contents || !section.contents.length) {
|
||||
|
|
|
@ -20,7 +20,6 @@ import { CoreEvents } from '@singletons/events';
|
|||
import { CoreLogger } from '@singletons/logger';
|
||||
import { CoreSitesCommonWSOptions, CoreSites, CoreSitesReadingStrategy } from '@services/sites';
|
||||
import { CoreTimeUtils } from '@services/utils/time';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreSite } from '@classes/sites/site';
|
||||
import { CoreCacheUpdateFrequency, CoreConstants, DownloadStatus } from '@/core/constants';
|
||||
import { makeSingleton, Translate } from '@singletons';
|
||||
|
@ -75,6 +74,7 @@ import {
|
|||
CORE_COURSE_STEALTH_MODULES_SECTION_ID,
|
||||
} from '../constants';
|
||||
import { CorePromiseUtils } from '@singletons/promise-utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
export type CoreCourseProgressUpdated = { progress: number; courseId: number };
|
||||
|
||||
|
@ -260,7 +260,7 @@ export class CoreCourseProvider {
|
|||
}
|
||||
|
||||
const course = await CoreCourses.getCourseByField('id', courseId, site.id);
|
||||
const formatOptions = CoreUtils.objectToKeyValueMap(
|
||||
const formatOptions = CoreObject.toKeyValueMap(
|
||||
course.courseformatoptions ?? [],
|
||||
'name',
|
||||
'value',
|
||||
|
@ -353,7 +353,7 @@ export class CoreCourseProvider {
|
|||
throw Error('WS core_completion_get_activities_completion_status failed');
|
||||
}
|
||||
|
||||
const completionStatus = CoreUtils.arrayToObject(data.statuses, 'cmid');
|
||||
const completionStatus = CoreArray.toObject(data.statuses, 'cmid');
|
||||
if (!includeOffline) {
|
||||
return completionStatus;
|
||||
}
|
||||
|
@ -412,7 +412,7 @@ export class CoreCourseProvider {
|
|||
js: (record) => ids.includes(record.cmId),
|
||||
});
|
||||
|
||||
return CoreUtils.arrayToObject(entries, 'cmId');
|
||||
return CoreArray.toObject(entries, 'cmId');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,7 +18,7 @@ import { CoreNetwork } from '@services/network';
|
|||
import { CoreSites } from '@services/sites';
|
||||
import { CoreText } from '@singletons/text';
|
||||
import { CoreTimeUtils } from '@services/utils/time';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { ACTIVITY_LOG_TABLE, CoreCourseActivityLogDBRecord } from './database/log';
|
||||
import { CoreStatusWithWarningsWSResponse } from '@services/ws';
|
||||
|
@ -84,7 +84,7 @@ export class CoreCourseLogHelperProvider {
|
|||
|
||||
const conditions: Partial<CoreCourseActivityLogDBRecord> = {
|
||||
ws,
|
||||
data: CoreUtils.sortAndStringify(data),
|
||||
data: CoreObject.sortAndStringify(data),
|
||||
};
|
||||
|
||||
await site.getDb().deleteRecords(ACTIVITY_LOG_TABLE, conditions);
|
||||
|
@ -264,7 +264,7 @@ export class CoreCourseLogHelperProvider {
|
|||
component,
|
||||
componentid: componentId,
|
||||
ws,
|
||||
data: CoreUtils.sortAndStringify(data),
|
||||
data: CoreObject.sortAndStringify(data),
|
||||
time: CoreTimeUtils.timestamp(),
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import { CoreFileHelper } from '@services/file-helper';
|
|||
import { CoreFilepool } from '@services/filepool';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreTimeUtils } from '@services/utils/time';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { CoreCourse, CoreCourseAnyModuleData, CoreCourseModuleContentFile } from './course';
|
||||
import { CoreCache } from '@classes/cache';
|
||||
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
|
||||
|
@ -1317,7 +1317,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
|
|||
previousTime?: number,
|
||||
): CourseUpdates {
|
||||
// Format the response to index it by module ID.
|
||||
CoreUtils.arrayToObject<false | CheckUpdatesWSInstance>(response.instances, 'id', result);
|
||||
CoreArray.toObject<false | CheckUpdatesWSInstance>(response.instances, 'id', result);
|
||||
|
||||
// Treat warnings, adding the not supported modules.
|
||||
response.warnings?.forEach((warning) => {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites';
|
||||
import {
|
||||
CoreCourseAnyCourseData,
|
||||
|
@ -157,7 +157,7 @@ export class CoreCoursesHelperProvider {
|
|||
|
||||
// Get the extra data for the courses.
|
||||
return CoreCourses.getCoursesByFieldObservable('ids', courseIds, options).pipe(map(coursesInfosArray => {
|
||||
const coursesInfo = CoreUtils.arrayToObject(coursesInfosArray, 'id');
|
||||
const coursesInfo = CoreArray.toObject(coursesInfosArray, 'id');
|
||||
|
||||
courses.forEach((course) => {
|
||||
this.loadCourseExtraInfo(course, coursesInfo[course.id], loadCategoryNames);
|
||||
|
|
|
@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
|
|||
import { CoreError } from '@classes/errors/error';
|
||||
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { CoreLogger } from '@singletons/logger';
|
||||
import { CoreEditorDraft, CoreEditorDraftPrimaryData, DRAFT_TABLE } from './database/editor';
|
||||
|
@ -82,7 +82,7 @@ export class CoreEditorOfflineProvider {
|
|||
contextlevel: contextLevel,
|
||||
contextinstanceid: contextInstanceId,
|
||||
elementid: elementId,
|
||||
extraparams: CoreUtils.sortAndStringify(extraParams || {}),
|
||||
extraparams: CoreObject.sortAndStringify(extraParams || {}),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import { CoreFile, CoreFileProvider, CoreFileProgressEvent } from '@services/fil
|
|||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreMimetypeUtils } from '@services/utils/mimetype';
|
||||
import { CoreText } from '@singletons/text';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { makeSingleton, Translate, Camera, ActionSheetController } from '@singletons';
|
||||
import { CoreLogger } from '@singletons/logger';
|
||||
import { CoreCanceledError } from '@classes/errors/cancelederror';
|
||||
|
@ -635,8 +635,8 @@ export class CoreFileUploaderHelperProvider {
|
|||
};
|
||||
|
||||
if (fromAlbum) {
|
||||
const imageSupported = !mimetypes || CoreUtils.indexOfRegexp(mimetypes, /^image\//) > -1;
|
||||
const videoSupported = !mimetypes || CoreUtils.indexOfRegexp(mimetypes, /^video\//) > -1;
|
||||
const imageSupported = !mimetypes || CoreArray.indexOfRegexp(mimetypes, /^image\//) > -1;
|
||||
const videoSupported = !mimetypes || CoreArray.indexOfRegexp(mimetypes, /^video\//) > -1;
|
||||
|
||||
options.sourceType = Camera.PictureSourceType.PHOTOLIBRARY;
|
||||
options.popoverOptions = {
|
||||
|
|
|
@ -47,6 +47,7 @@ import { CoreLoadings } from '@services/loadings';
|
|||
import { convertTextToHTMLElement } from '@/core/utils/create-html-element';
|
||||
import { CoreCourseAccessDataType } from '@features/course/constants';
|
||||
import { CorePromiseUtils } from '@singletons/promise-utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
|
||||
export const GRADES_PAGE_NAME = 'grades';
|
||||
export const GRADES_PARTICIPANTS_PAGE_NAME = 'participant-grades';
|
||||
|
@ -271,7 +272,7 @@ export class CoreGradesHelperProvider {
|
|||
|
||||
try {
|
||||
const courses = await CoreCourses.getUserCourses(undefined, undefined, CoreSitesReadingStrategy.ONLY_CACHE);
|
||||
const coursesMap = CoreUtils.arrayToObject(courses, 'id');
|
||||
const coursesMap = CoreArray.toObject(courses, 'id');
|
||||
|
||||
coursesWereMissing = this.addCourseData(grades, coursesMap);
|
||||
} catch {
|
||||
|
@ -282,7 +283,7 @@ export class CoreGradesHelperProvider {
|
|||
if (coursesWereMissing) {
|
||||
const courses = await CoreCourses.getCoursesByField('ids', grades.map((grade) => grade.courseid).join(','));
|
||||
const coursesMap =
|
||||
CoreUtils.arrayToObject(courses as Record<string, unknown>[], 'id') as
|
||||
CoreArray.toObject(courses as Record<string, unknown>[], 'id') as
|
||||
Record<string, CoreEnrolledCourseData> |
|
||||
Record<string, CoreCourseSearchedData>;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import { CoreH5P } from '@features/h5p/services/h5p';
|
|||
import { Translate } from '@singletons';
|
||||
import { CoreH5PCore, CoreH5PLibraryData, CoreH5PLibraryAddonData, CoreH5PContentDepsTreeDependency } from './core';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
const ALLOWED_STYLEABLE_TAGS = ['span', 'p', 'div', 'h1', 'h2', 'h3', 'table', 'col', 'figure', 'td', 'th', 'li'];
|
||||
|
||||
|
@ -354,7 +355,7 @@ export class CoreH5PContentValidator {
|
|||
}
|
||||
|
||||
if (!isArray) {
|
||||
list = CoreUtils.objectToArray(<Record<string, unknown>> list);
|
||||
list = CoreObject.toArray(<Record<string, unknown>> list);
|
||||
}
|
||||
|
||||
if (!list.length) {
|
||||
|
@ -677,7 +678,7 @@ export class CoreH5PContentValidator {
|
|||
*/
|
||||
protected filterXssSplit(tags: string[], store: boolean = false): string {
|
||||
if (store) {
|
||||
this.allowedHtml = CoreUtils.arrayToObject(tags);
|
||||
this.allowedHtml = CoreArray.toObject(tags);
|
||||
|
||||
return '';
|
||||
}
|
||||
|
|
|
@ -961,7 +961,7 @@ export class CoreH5PCore {
|
|||
if (params.match(pattern)) {
|
||||
return true;
|
||||
}
|
||||
} else if (typeof params == 'object') {
|
||||
} else if (typeof params === 'object') {
|
||||
for (const key in params) {
|
||||
const value = params[key];
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import { CoreSites, CoreLoginSiteInfo, CoreSiteBasicInfo } from '@services/sites
|
|||
import { CoreWS, CoreWSExternalWarning } from '@services/ws';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreText } from '@singletons/text';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreConstants } from '@/core/constants';
|
||||
import { CoreSite } from '@classes/sites/site';
|
||||
import { CoreError } from '@classes/errors/error';
|
||||
|
@ -1368,7 +1368,7 @@ export class CoreLoginHelperProvider {
|
|||
return;
|
||||
}));
|
||||
|
||||
accountsList.otherSites = CoreUtils.objectToArray(otherSites);
|
||||
accountsList.otherSites = CoreObject.toArray(otherSites);
|
||||
|
||||
return accountsList;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import { CoreSites } from '@services/sites';
|
|||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||
import { CoreTabsOutletComponent, CoreTabsOutletTab } from '@components/tabs-outlet/tabs-outlet';
|
||||
import { CoreMainMenuHomeDelegate, CoreMainMenuHomeHandlerToDisplay } from '../../services/home-delegate';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { CoreMainMenuHomeHandlerService } from '@features/mainmenu/services/handlers/mainmenu';
|
||||
|
||||
/**
|
||||
|
@ -62,7 +62,7 @@ export class CoreMainMenuHomePage implements OnInit {
|
|||
initHandlers(handlers: CoreMainMenuHomeHandlerToDisplay[]): void {
|
||||
// Re-build the list of tabs.
|
||||
const loaded = CoreMainMenuHomeDelegate.areHandlersLoaded();
|
||||
const handlersMap = CoreUtils.arrayToObject(handlers, 'title');
|
||||
const handlersMap = CoreArray.toObject(handlers, 'title');
|
||||
const newTabs = handlers.map((handler): CoreTabsOutletTab => {
|
||||
const tab = this.tabs.find(tab => tab.title == handler.title);
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ import { CoreFile } from '@services/file';
|
|||
import { CoreSites } from '@services/sites';
|
||||
import { CoreText } from '@singletons/text';
|
||||
import { CoreTimeUtils } from '@services/utils/time';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { CoreWSExternalFile } from '@services/ws';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { CorePath } from '@singletons/path';
|
||||
|
@ -37,6 +37,7 @@ import {
|
|||
QUESTION_NEEDS_GRADING_STATE_CLASSES,
|
||||
QUESTION_TODO_STATE_CLASSES,
|
||||
} from '@features/question/constants';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
const QUESTION_PREFIX_REGEX = /q\d+:(\d+)_/;
|
||||
const STATES: Record<string, CoreQuestionState> = {
|
||||
|
@ -150,7 +151,7 @@ export class CoreQuestionProvider {
|
|||
*/
|
||||
compareAllAnswers(prevAnswers: Record<string, unknown>, newAnswers: Record<string, unknown>): boolean {
|
||||
// Get all the keys.
|
||||
const keys = CoreUtils.mergeArraysWithoutDuplicates(Object.keys(prevAnswers), Object.keys(newAnswers));
|
||||
const keys = CoreArray.mergeWithoutDuplicates(Object.keys(prevAnswers), Object.keys(newAnswers));
|
||||
|
||||
// Check that all the keys have the same value on both objects.
|
||||
for (const i in keys) {
|
||||
|
@ -158,7 +159,7 @@ export class CoreQuestionProvider {
|
|||
|
||||
// Ignore extra answers like sequencecheck or certainty.
|
||||
if (!this.isExtraAnswer(key[0])) {
|
||||
if (!CoreUtils.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, key)) {
|
||||
if (!CoreObject.sameAtKeyMissingIsBlank(prevAnswers, newAnswers, key)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,13 +18,13 @@ import { CoreSite } from '@classes/sites/site';
|
|||
import { CoreUser } from '@features/user/services/user';
|
||||
import { CoreNetwork } from '@services/network';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreWSExternalWarning } from '@services/ws';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { CoreEvents } from '@singletons/events';
|
||||
import { CoreRatingOffline } from './rating-offline';
|
||||
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
|
||||
import { CoreWSError } from '@classes/errors/wserror';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
const ROOT_CACHE_KEY = 'CoreRating:';
|
||||
|
||||
|
@ -351,8 +351,8 @@ export class CoreRatingProvider {
|
|||
});
|
||||
|
||||
if (result) {
|
||||
result.scales = CoreUtils.objectToArray(scales);
|
||||
result.ratings = CoreUtils.objectToArray(ratings);
|
||||
result.scales = CoreObject.toArray(scales);
|
||||
result.ratings = CoreObject.toArray(ratings);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
|
||||
import { CoreSiteBasicInfo, CoreSites } from '@services/sites';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||
|
||||
import { CoreSettingsHelper } from '../../services/settings-helper';
|
||||
|
@ -129,7 +129,7 @@ export class CoreSettingsSpaceUsagePage implements OnInit, OnDestroy {
|
|||
}
|
||||
});
|
||||
|
||||
this.accountsList.otherSites = CoreUtils.objectToArray(otherSites);
|
||||
this.accountsList.otherSites = CoreObject.toArray(otherSites);
|
||||
this.accountsList.count = sites.length;
|
||||
|
||||
this.totalSpaceUsage = totalSize;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
import { CoreSitePlugins, CoreSitePluginsInitHandlerData } from '../services/siteplugins';
|
||||
|
||||
/**
|
||||
|
@ -55,7 +55,7 @@ export class CoreSitePluginsCompileInitComponent {
|
|||
// Load first template.
|
||||
if (this.handlerSchema.methodTemplates?.length) {
|
||||
this.content = this.handlerSchema.methodTemplates[0].html;
|
||||
this.jsData.CONTENT_TEMPLATES = CoreUtils.objectToKeyValueMap(
|
||||
this.jsData.CONTENT_TEMPLATES = CoreObject.toKeyValueMap(
|
||||
this.handlerSchema.methodTemplates,
|
||||
'id',
|
||||
'html',
|
||||
|
|
|
@ -34,6 +34,7 @@ import { CoreEnrolAction, CoreEnrolInfoIcon } from '@features/enrol/services/enr
|
|||
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
|
||||
import { CoreUserProfileHandlerType } from '@features/user/services/user-delegate';
|
||||
import { CORE_SITE_PLUGINS_COMPONENT, CORE_SITE_PLUGINS_UPDATE_COURSE_CONTENT } from '../constants';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
/**
|
||||
* Service to provide functionalities regarding site plugins.
|
||||
|
@ -156,13 +157,13 @@ export class CoreSitePluginsProvider {
|
|||
data = Object.assign(data, initResult.jsResult || {});
|
||||
|
||||
// Now add some data returned by the init WS call.
|
||||
data.INIT_TEMPLATES = CoreUtils.objectToKeyValueMap(initResult.templates, 'id', 'html');
|
||||
data.INIT_TEMPLATES = CoreObject.toKeyValueMap(initResult.templates, 'id', 'html');
|
||||
data.INIT_OTHERDATA = initResult.otherdata;
|
||||
}
|
||||
|
||||
if (contentResult) {
|
||||
// Now add the data returned by the content WS call.
|
||||
data.CONTENT_TEMPLATES = CoreUtils.objectToKeyValueMap(contentResult.templates, 'id', 'html');
|
||||
data.CONTENT_TEMPLATES = CoreObject.toKeyValueMap(contentResult.templates, 'id', 'html');
|
||||
data.CONTENT_OTHERDATA = contentResult.otherdata;
|
||||
}
|
||||
|
||||
|
@ -177,7 +178,7 @@ export class CoreSitePluginsProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
getCallWSCacheKey(method: string, data: Record<string, unknown>): string {
|
||||
return this.getCallWSCommonCacheKey(method) + ':' + CoreUtils.sortAndStringify(data);
|
||||
return this.getCallWSCommonCacheKey(method) + ':' + CoreObject.sortAndStringify(data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,7 +220,7 @@ export class CoreSitePluginsProvider {
|
|||
const data: CoreSitePluginsGetContentWSParams = {
|
||||
component: component,
|
||||
method: method,
|
||||
args: CoreUtils.objectToArrayOfObjects(argsToSend, 'name', 'value', true),
|
||||
args: CoreObject.toArrayOfObjects(argsToSend, 'name', 'value', true),
|
||||
};
|
||||
|
||||
preSets = preSets || {};
|
||||
|
@ -230,7 +231,7 @@ export class CoreSitePluginsProvider {
|
|||
|
||||
let otherData: Record<string, unknown> = {};
|
||||
if (result.otherdata) {
|
||||
otherData = <Record<string, unknown>> CoreUtils.objectToKeyValueMap(result.otherdata, 'name', 'value');
|
||||
otherData = <Record<string, unknown>> CoreObject.toKeyValueMap(result.otherdata, 'name', 'value');
|
||||
|
||||
// Try to parse all properties that could be JSON encoded strings.
|
||||
for (const name in otherData) {
|
||||
|
@ -255,7 +256,7 @@ export class CoreSitePluginsProvider {
|
|||
*/
|
||||
protected getContentCacheKey(component: string, method: string, args: Record<string, unknown>): string {
|
||||
return CoreSitePluginsProvider.ROOT_CACHE_KEY + 'content:' + component + ':' + method +
|
||||
':' + CoreUtils.sortAndStringify(args);
|
||||
':' + CoreObject.sortAndStringify(args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -346,7 +347,7 @@ export class CoreSitePluginsProvider {
|
|||
* @returns Plugin list ws info.
|
||||
*/
|
||||
getCurrentSitePluginList(): CoreSitePluginsWSPlugin[] {
|
||||
return CoreUtils.objectToArray(this.sitePlugins).map((plugin) => plugin.plugin);
|
||||
return CoreObject.toArray(this.sitePlugins).map((plugin) => plugin.plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -507,7 +508,7 @@ export class CoreSitePluginsProvider {
|
|||
for (const i in useOtherData) {
|
||||
const name = useOtherData[i];
|
||||
|
||||
if (typeof otherData[name] == 'object' && otherData[name] !== null) {
|
||||
if (typeof otherData[name] === 'object' && otherData[name] !== null) {
|
||||
// Stringify objects.
|
||||
args[name] = JSON.stringify(otherData[name]);
|
||||
} else {
|
||||
|
@ -517,7 +518,7 @@ export class CoreSitePluginsProvider {
|
|||
} else {
|
||||
// Add all the data to args.
|
||||
for (const name in otherData) {
|
||||
if (typeof otherData[name] == 'object' && otherData[name] !== null) {
|
||||
if (typeof otherData[name] === 'object' && otherData[name] !== null) {
|
||||
// Stringify objects.
|
||||
args[name] = JSON.stringify(otherData[name]);
|
||||
} else {
|
||||
|
|
|
@ -27,7 +27,7 @@ import { CoreMimetypeUtils } from '@services/utils/mimetype';
|
|||
import { CoreText } from '@singletons/text';
|
||||
import { CoreTimeUtils } from '@services/utils/time';
|
||||
import { CoreUrl, CoreUrlPartNames } from '@singletons/url';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreArray } from '@singletons/array';
|
||||
import { CoreError } from '@classes/errors/error';
|
||||
import { DownloadStatus } from '@/core/constants';
|
||||
import { ApplicationInit, makeSingleton, NgZone, Translate } from '@singletons';
|
||||
|
@ -650,7 +650,7 @@ export class CoreFilepoolProvider {
|
|||
]);
|
||||
|
||||
// Notify now.
|
||||
const filesLinksMap = CoreUtils.arrayToObjectMultiple(filesLinks, 'fileId');
|
||||
const filesLinksMap = CoreArray.toObjectMultiple(filesLinks, 'fileId');
|
||||
|
||||
filesEntries.forEach(entry => this.notifyFileDeleted(siteId, entry.fileId, filesLinksMap[entry.fileId] || []));
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ export class CoreGeolocationProvider {
|
|||
*/
|
||||
protected isCordovaPermissionDeniedError(error?: CoreAnyError | GeolocationPositionError): boolean {
|
||||
return !!error &&
|
||||
typeof error == 'object' &&
|
||||
typeof error === 'object' &&
|
||||
'code' in error &&
|
||||
'PERMISSION_DENIED' in error &&
|
||||
error.code === error.PERMISSION_DENIED;
|
||||
|
|
|
@ -290,7 +290,7 @@ export class CoreLocalNotificationsProvider {
|
|||
scheduled.forEach((notif) => {
|
||||
notif.data = this.parseNotificationData(notif.data);
|
||||
|
||||
if (notif.id && typeof notif.data == 'object' && notif.data.siteId === siteId) {
|
||||
if (notif.id && typeof notif.data === 'object' && notif.data.siteId === siteId) {
|
||||
ids.push(notif.id);
|
||||
}
|
||||
});
|
||||
|
@ -563,7 +563,7 @@ export class CoreLocalNotificationsProvider {
|
|||
|
||||
try {
|
||||
// Check if request is valid.
|
||||
if (typeof request != 'object' || request.table === undefined || request.id === undefined) {
|
||||
if (typeof request !== 'object' || request.table === undefined || request.id === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -461,7 +461,7 @@ export class CoreNavigatorService {
|
|||
return route;
|
||||
}
|
||||
|
||||
if (routeData && CoreUtils.basicLeftCompare(routeData, this.getRouteData(route), 3)) {
|
||||
if (routeData && CoreObject.basicLeftCompare(routeData, this.getRouteData(route), 3)) {
|
||||
return route;
|
||||
}
|
||||
|
||||
|
@ -607,7 +607,7 @@ export class CoreNavigatorService {
|
|||
protected replaceObjectParams(queryParams?: Params | null): void {
|
||||
for (const name in queryParams) {
|
||||
const value = queryParams[name];
|
||||
if (typeof value != 'object' || value === null) {
|
||||
if (typeof value !== 'object' || value === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1292,7 +1292,7 @@ export class CoreSitesProvider {
|
|||
return !!this.currentSite;
|
||||
}
|
||||
|
||||
const siteId = typeof site == 'object' ? site.getId() : site;
|
||||
const siteId = typeof site === 'object' ? site.getId() : site;
|
||||
|
||||
return this.currentSite.getId() === siteId;
|
||||
}
|
||||
|
|
|
@ -447,7 +447,7 @@ export class CoreDomUtilsProvider {
|
|||
let extraInfo = '';
|
||||
let errorMessage: string | undefined;
|
||||
|
||||
if (typeof error == 'object') {
|
||||
if (typeof error === 'object') {
|
||||
if (this.debugDisplay) {
|
||||
// Get the debug info. Escape the HTML so it is displayed as it is in the view.
|
||||
if ('debuginfo' in error && error.debuginfo) {
|
||||
|
|
|
@ -455,7 +455,7 @@ export class CoreIframeUtilsProvider {
|
|||
return;
|
||||
}
|
||||
|
||||
if (element.tagName.toLowerCase() == 'object') {
|
||||
if (element.tagName.toLowerCase() === 'object') {
|
||||
element.setAttribute('data', url);
|
||||
} else {
|
||||
element.setAttribute('src', url);
|
||||
|
@ -509,7 +509,7 @@ export class CoreIframeUtilsProvider {
|
|||
(!link.target || link.target == '_self')
|
||||
) {
|
||||
// Load the link inside the frame itself.
|
||||
if (element.tagName.toLowerCase() == 'object') {
|
||||
if (element.tagName.toLowerCase() === 'object') {
|
||||
element.setAttribute('data', link.href);
|
||||
} else {
|
||||
element.setAttribute('src', link.href);
|
||||
|
@ -546,7 +546,7 @@ export class CoreIframeUtilsProvider {
|
|||
} else if (CorePlatform.isIOS() && (!link.target || link.target == '_self') && element) {
|
||||
// In cordova ios 4.1.0 links inside iframes stopped working. We'll manually treat them.
|
||||
event && event.preventDefault();
|
||||
if (element.tagName.toLowerCase() == 'object') {
|
||||
if (element.tagName.toLowerCase() === 'object') {
|
||||
element.setAttribute('data', link.href);
|
||||
} else {
|
||||
element.setAttribute('src', link.href);
|
||||
|
|
|
@ -424,10 +424,10 @@ export class CoreMimetypeUtilsProvider {
|
|||
let mimetype: string | undefined = '';
|
||||
let extension: string | undefined = '';
|
||||
|
||||
if (typeof obj == 'object' && CoreFileUtils.isFileEntry(obj)) {
|
||||
if (typeof obj === 'object' && CoreFileUtils.isFileEntry(obj)) {
|
||||
// It's a FileEntry. Don't use the file function because it's asynchronous and the type isn't reliable.
|
||||
filename = obj.name;
|
||||
} else if (typeof obj == 'object') {
|
||||
} else if (typeof obj === 'object') {
|
||||
filename = obj.filename || '';
|
||||
mimetype = obj.mimetype || '';
|
||||
} else {
|
||||
|
|
|
@ -30,6 +30,7 @@ import { CoreErrorHelper } from '@services/error-helper';
|
|||
import { CorePromiseUtils, OrderedPromiseData } from '@singletons/promise-utils';
|
||||
import { CoreOpener, CoreOpenerOpenFileOptions, CoreOpenerOpenInBrowserOptions } from '@singletons/opener';
|
||||
import { CoreCountries, CoreCountry } from '@singletons/countries';
|
||||
import { CoreObject } from '@singletons/object';
|
||||
|
||||
export type TreeNode<T> = T & { children: TreeNode<T>[] };
|
||||
|
||||
|
@ -89,19 +90,14 @@ export class CoreUtilsProvider {
|
|||
* @param propertyName The name of the property to use as the key. If not provided, the whole item will be used.
|
||||
* @param result Object where to put the properties. If not defined, a new object will be created.
|
||||
* @returns The object.
|
||||
* @deprecated since 5.0. Use CoreArray.toObject instead.
|
||||
*/
|
||||
arrayToObject<T>(
|
||||
array: T[] = [],
|
||||
propertyName?: string,
|
||||
result: Record<string, T> = {},
|
||||
): Record<string, T> {
|
||||
for (const entry of array) {
|
||||
const key = propertyName ? entry[propertyName] : entry;
|
||||
|
||||
result[key] = entry;
|
||||
}
|
||||
|
||||
return result;
|
||||
return CoreArray.toObject(array, propertyName, result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,22 +120,14 @@ export class CoreUtilsProvider {
|
|||
* @param propertyName The name of the property to use as the key. If not provided, the whole item will be used.
|
||||
* @param result Object where to put the properties. If not defined, a new object will be created.
|
||||
* @returns The object.
|
||||
* @deprecated since 5.0. Use CoreArray.toObjectMultiple instead.
|
||||
*/
|
||||
arrayToObjectMultiple<T>(
|
||||
array: T[] = [],
|
||||
propertyName?: string,
|
||||
result: Record<string, T[]> = {},
|
||||
): Record<string, T[]> {
|
||||
for (const entry of array) {
|
||||
const key = propertyName ? entry[propertyName] : entry;
|
||||
if (result[key] === undefined) {
|
||||
result[key] = [];
|
||||
}
|
||||
|
||||
result[key].push(entry);
|
||||
}
|
||||
|
||||
return result;
|
||||
return CoreArray.toObjectMultiple(array, propertyName, result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,6 +141,7 @@ export class CoreUtilsProvider {
|
|||
* @param level Current deep level (when comparing objects).
|
||||
* @param undefinedIsNull True if undefined is equal to null. Defaults to true.
|
||||
* @returns Whether both items are equal.
|
||||
* @deprecated since 5.0. Use CoreObject.basicLeftCompare instead.
|
||||
*/
|
||||
basicLeftCompare(
|
||||
itemA: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
|
@ -161,43 +150,7 @@ export class CoreUtilsProvider {
|
|||
level: number = 0,
|
||||
undefinedIsNull: boolean = true,
|
||||
): boolean {
|
||||
if (typeof itemA == 'function' || typeof itemB == 'function') {
|
||||
return true; // Don't compare functions.
|
||||
} else if (typeof itemA == 'object' && typeof itemB == 'object') {
|
||||
if (level >= maxLevels) {
|
||||
return true; // Max deep reached.
|
||||
}
|
||||
|
||||
let equal = true;
|
||||
for (const name in itemA) {
|
||||
const value = itemA[name];
|
||||
if (name == '$$hashKey') {
|
||||
// Ignore $$hashKey property since it's a "calculated" property.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!this.basicLeftCompare(value, itemB[name], maxLevels, level + 1)) {
|
||||
equal = false;
|
||||
}
|
||||
}
|
||||
|
||||
return equal;
|
||||
} else {
|
||||
if (undefinedIsNull && (
|
||||
(itemA === undefined && itemB === null) || (itemA === null && itemB === undefined))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We'll treat "2" and 2 as the same value.
|
||||
const floatA = parseFloat(itemA);
|
||||
const floatB = parseFloat(itemB);
|
||||
|
||||
if (!isNaN(floatA) && !isNaN(floatB)) {
|
||||
return floatA == floatB;
|
||||
}
|
||||
|
||||
return itemA === itemB;
|
||||
}
|
||||
return CoreObject.basicLeftCompare(itemA, itemB, maxLevels, level, undefinedIsNull);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -291,7 +244,7 @@ export class CoreUtilsProvider {
|
|||
}
|
||||
|
||||
return newArray;
|
||||
} else if (this.isObject(source)) {
|
||||
} else if (CoreObject.isObject(source)) {
|
||||
// Check if the object shouldn't be copied.
|
||||
if (source.toString && this.DONT_CLONE.indexOf(source.toString()) != -1) {
|
||||
// Object shouldn't be copied, return it as it is.
|
||||
|
@ -383,32 +336,10 @@ export class CoreUtilsProvider {
|
|||
* @param obj Object to flatten.
|
||||
* @param useDotNotation Whether to use dot notation '.' or square brackets '['.
|
||||
* @returns Flattened object.
|
||||
* @deprecated since 5.0. Use CoreObject.flatten instead.
|
||||
*/
|
||||
flattenObject(obj: Record<string, unknown>, useDotNotation?: boolean): Record<string, unknown> {
|
||||
const toReturn = {};
|
||||
|
||||
for (const name in obj) {
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const value = obj[name];
|
||||
if (typeof value == 'object' && !Array.isArray(value)) {
|
||||
const flatObject = this.flattenObject(value as Record<string, unknown>);
|
||||
for (const subName in flatObject) {
|
||||
if (!Object.prototype.hasOwnProperty.call(flatObject, subName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const newName = useDotNotation ? name + '.' + subName : name + '[' + subName + ']';
|
||||
toReturn[newName] = flatObject[subName];
|
||||
}
|
||||
} else {
|
||||
toReturn[name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
return CoreObject.flatten(obj, useDotNotation);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -650,9 +581,10 @@ export class CoreUtilsProvider {
|
|||
*
|
||||
* @param object Variable.
|
||||
* @returns Type guard indicating if this is an object.
|
||||
* @deprecated since 5.0. Use CoreObject.isObject instead.
|
||||
*/
|
||||
isObject(object: unknown): object is Record<string, unknown> {
|
||||
return typeof object === 'object' && object !== null;
|
||||
return CoreObject.isObject(object);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -672,22 +604,10 @@ export class CoreUtilsProvider {
|
|||
* @param array Array to search.
|
||||
* @param regex RegExp to apply to each string.
|
||||
* @returns Index of the first string that matches the RegExp. -1 if not found.
|
||||
* @deprecated since 4.4. Use CoreArray.indexOfRegexp instead.
|
||||
*/
|
||||
indexOfRegexp(array: string[], regex: RegExp): number {
|
||||
if (!array || !array.length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const entry = array[i];
|
||||
const matches = entry.match(regex);
|
||||
|
||||
if (matches && matches.length) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return CoreArray.indexOfRegexp(array, regex);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -787,9 +707,10 @@ export class CoreUtilsProvider {
|
|||
* @param array2 The second array.
|
||||
* @param [key] Key of the property that must be unique. If not specified, the whole entry.
|
||||
* @returns Merged array.
|
||||
* @deprecated since 5.0. Use CoreArray.mergeWithoutDuplicates instead.
|
||||
*/
|
||||
mergeArraysWithoutDuplicates<T>(array1: T[], array2: T[], key?: string): T[] {
|
||||
return CoreArray.unique(array1.concat(array2), key) as T[];
|
||||
return CoreArray.mergeWithoutDuplicates(array1, array2, key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -855,9 +776,10 @@ export class CoreUtilsProvider {
|
|||
*
|
||||
* @param obj Object to convert.
|
||||
* @returns Array with the values of the object but losing the keys.
|
||||
* @deprecated since 5.0. Use CoreObject.toArray instead.
|
||||
*/
|
||||
objectToArray<T>(obj: Record<string, T>): T[] {
|
||||
return Object.keys(obj).map((key) => obj[key]);
|
||||
return CoreObject.toArray(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -871,6 +793,7 @@ export class CoreUtilsProvider {
|
|||
* @param sortByKey True to sort keys alphabetically, false otherwise. Has priority over sortByValue.
|
||||
* @param sortByValue True to sort values alphabetically, false otherwise.
|
||||
* @returns Array of objects with the name & value of each property.
|
||||
* @deprecated since 5.0. Use CoreObject.toArrayOfObjects instead.
|
||||
*/
|
||||
objectToArrayOfObjects<
|
||||
A extends Record<string,unknown> = Record<string, unknown>,
|
||||
|
@ -882,53 +805,7 @@ export class CoreUtilsProvider {
|
|||
sortByKey?: boolean,
|
||||
sortByValue?: boolean,
|
||||
): A[] {
|
||||
// Get the entries from an object or primitive value.
|
||||
const getEntries = (elKey: string, value: unknown): Record<string, unknown>[] | unknown => {
|
||||
if (value === undefined || value == null) {
|
||||
// Filter undefined and null values.
|
||||
return;
|
||||
} else if (this.isObject(value)) {
|
||||
// It's an object, return at least an entry for each property.
|
||||
const keys = Object.keys(value);
|
||||
let entries: unknown[] = [];
|
||||
|
||||
keys.forEach((key) => {
|
||||
const newElKey = elKey ? elKey + '[' + key + ']' : key;
|
||||
const subEntries = getEntries(newElKey, value[key]);
|
||||
|
||||
if (subEntries) {
|
||||
entries = entries.concat(subEntries);
|
||||
}
|
||||
});
|
||||
|
||||
return entries;
|
||||
} else {
|
||||
// Not an object, return a single entry.
|
||||
const entry = {};
|
||||
entry[keyName] = elKey;
|
||||
entry[valueName] = value;
|
||||
|
||||
return entry;
|
||||
}
|
||||
};
|
||||
|
||||
if (!obj) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// "obj" will always be an object, so "entries" will always be an array.
|
||||
const entries = getEntries('', obj) as A[];
|
||||
if (sortByKey || sortByValue) {
|
||||
return entries.sort((a, b) => {
|
||||
if (sortByKey) {
|
||||
return (a[keyName] as number) >= (b[keyName] as number) ? 1 : -1;
|
||||
} else {
|
||||
return (a[valueName] as number) >= (b[valueName] as number) ? 1 : -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return entries;
|
||||
return CoreObject.toArrayOfObjects(obj, keyName, valueName, sortByKey, sortByValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -940,6 +817,7 @@ export class CoreUtilsProvider {
|
|||
* @param valueName Name of the properties where the values are stored.
|
||||
* @param keyPrefix Key prefix if neededs to delete it.
|
||||
* @returns Object.
|
||||
* @deprecated since 5.0. Use CoreObject.toKeyValueMap instead.
|
||||
*/
|
||||
objectToKeyValueMap<T = unknown>(
|
||||
objects: Record<string, unknown>[],
|
||||
|
@ -947,15 +825,7 @@ export class CoreUtilsProvider {
|
|||
valueName: string,
|
||||
keyPrefix?: string,
|
||||
): {[name: string]: T} {
|
||||
const prefixSubstr = keyPrefix ? keyPrefix.length : 0;
|
||||
const mapped = {};
|
||||
objects.forEach((item) => {
|
||||
const keyValue = item[keyName] as string;
|
||||
const key = prefixSubstr > 0 ? keyValue.substring(prefixSubstr) : keyValue;
|
||||
mapped[key] = item[valueName];
|
||||
});
|
||||
|
||||
return mapped;
|
||||
return CoreObject.toKeyValueMap(objects, keyName, valueName, keyPrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -964,29 +834,10 @@ export class CoreUtilsProvider {
|
|||
* @param object Object to convert.
|
||||
* @param removeEmpty Whether to remove params whose value is null/undefined.
|
||||
* @returns GET params.
|
||||
* @deprecated since 5.0. Use CoreObject.toGetParams instead.
|
||||
*/
|
||||
objectToGetParams(object: Record<string, unknown>, removeEmpty: boolean = true): string {
|
||||
// First of all, flatten the object so all properties are in the first level.
|
||||
const flattened = this.flattenObject(object);
|
||||
let result = '';
|
||||
let joinChar = '';
|
||||
|
||||
for (const name in flattened) {
|
||||
let value = flattened[name];
|
||||
|
||||
if (removeEmpty && (value === null || value === undefined)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof value == 'boolean') {
|
||||
value = value ? 1 : 0;
|
||||
}
|
||||
|
||||
result += joinChar + name + '=' + value;
|
||||
joinChar = '&';
|
||||
}
|
||||
|
||||
return result;
|
||||
return CoreObject.toGetParams(object, removeEmpty);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -995,6 +846,7 @@ export class CoreUtilsProvider {
|
|||
* @param data Object.
|
||||
* @param prefix Prefix to add.
|
||||
* @returns Prefixed object.
|
||||
* @deprecated since 5.0. Not used anymore
|
||||
*/
|
||||
prefixKeys(data: Record<string, unknown>, prefix: string): Record<string, unknown> {
|
||||
const newObj = {};
|
||||
|
@ -1012,9 +864,10 @@ export class CoreUtilsProvider {
|
|||
*
|
||||
* @param enumeration Enumeration object.
|
||||
* @returns Keys of the enumeration.
|
||||
* @deprecated since 5.0. Use CoreObject.enumKeys instead.
|
||||
*/
|
||||
enumKeys<O extends object, K extends keyof O = keyof O>(enumeration: O): K[] {
|
||||
return Object.keys(enumeration).filter(k => Number.isNaN(+k)) as K[];
|
||||
return CoreObject.enumKeys(enumeration);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1048,23 +901,14 @@ export class CoreUtilsProvider {
|
|||
* @param obj2 The second object or array.
|
||||
* @param key Key to check.
|
||||
* @returns Whether the two objects/arrays have the same value (or lack of one) for a given key.
|
||||
* @deprecated since 5.0. Use CoreObject.sameAtKeyMissingIsBlank instead.
|
||||
*/
|
||||
sameAtKeyMissingIsBlank(
|
||||
obj1: Record<string, unknown> | unknown[],
|
||||
obj2: Record<string, unknown> | unknown[],
|
||||
key: string,
|
||||
): boolean {
|
||||
let value1 = obj1[key] !== undefined ? obj1[key] : '';
|
||||
let value2 = obj2[key] !== undefined ? obj2[key] : '';
|
||||
|
||||
if (typeof value1 == 'number' || typeof value1 == 'boolean') {
|
||||
value1 = '' + value1;
|
||||
}
|
||||
if (typeof value2 == 'number' || typeof value2 == 'boolean') {
|
||||
value2 = '' + value2;
|
||||
}
|
||||
|
||||
return value1 === value2;
|
||||
return CoreObject.sameAtKeyMissingIsBlank(obj1, obj2, key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1073,9 +917,11 @@ export class CoreUtilsProvider {
|
|||
*
|
||||
* @param obj Object to stringify.
|
||||
* @returns Stringified object.
|
||||
* @deprecated since 5.0. Use CoreObject.sortAndStringify instead.
|
||||
*/
|
||||
sortAndStringify(obj: Record<string, unknown>): string {
|
||||
return JSON.stringify(this.sortProperties(obj));
|
||||
return CoreObject.sortAndStringify(obj);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1083,19 +929,10 @@ export class CoreUtilsProvider {
|
|||
*
|
||||
* @param obj The object to sort. If it isn't an object, the original value will be returned.
|
||||
* @returns Sorted object.
|
||||
* @deprecated since 5.0. Use CoreObject.sortProperties instead.
|
||||
*/
|
||||
sortProperties<T>(obj: T): T {
|
||||
if (obj != null && typeof obj == 'object' && !Array.isArray(obj)) {
|
||||
// It's an object, sort it.
|
||||
return Object.keys(obj).sort().reduce((accumulator, key) => {
|
||||
// Always call sort with the value. If it isn't an object, the original value will be returned.
|
||||
accumulator[key] = this.sortProperties(obj[key]);
|
||||
|
||||
return accumulator;
|
||||
}, {} as T);
|
||||
} else {
|
||||
return obj;
|
||||
}
|
||||
return CoreObject.sortProperties(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1103,16 +940,10 @@ export class CoreUtilsProvider {
|
|||
*
|
||||
* @param obj The object to sort. If it isn't an object, the original value will be returned.
|
||||
* @returns Sorted object.
|
||||
* @deprecated since 5.0. Use CoreObject.sortValues instead.
|
||||
*/
|
||||
sortValues<T>(obj: T): T {
|
||||
if (typeof obj == 'object' && !Array.isArray(obj)) {
|
||||
// It's an object, sort it. Convert it to an array to be able to sort it and then convert it back to object.
|
||||
const array = this.objectToArrayOfObjects(obj as Record<string, unknown>, 'name', 'value', false, true);
|
||||
|
||||
return this.objectToKeyValueMap(array, 'name', 'value') as unknown as T;
|
||||
} else {
|
||||
return obj;
|
||||
}
|
||||
return CoreObject.sortValues(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -170,7 +170,7 @@ export class CoreWSProvider {
|
|||
if (value == null) {
|
||||
// Skip null or undefined value.
|
||||
continue;
|
||||
} else if (typeof value == 'object') {
|
||||
} else if (typeof value === 'object') {
|
||||
// Object or array.
|
||||
value = this.convertValuesToString(value, stripUnicode);
|
||||
if (value == null) {
|
||||
|
@ -498,7 +498,7 @@ export class CoreWSProvider {
|
|||
}
|
||||
|
||||
// Check if error. Ajax layer should always return an object (if error) or an array (if success).
|
||||
if (!data || typeof data != 'object') {
|
||||
if (!data || typeof data !== 'object') {
|
||||
const message = CoreSites.isLoggedIn()
|
||||
? Translate.instant('core.siteunavailablehelp', { site: CoreSites.getCurrentSite()?.siteUrl })
|
||||
: Translate.instant('core.sitenotfoundhelp');
|
||||
|
@ -1090,7 +1090,7 @@ export class CoreWSProvider {
|
|||
}),
|
||||
},
|
||||
});
|
||||
} else if (typeof data != 'object') {
|
||||
} else if (typeof data !== 'object') {
|
||||
this.logger.warn('Upload file: Response of type "' + typeof data + '" received, expecting "object"');
|
||||
|
||||
throw await this.createCannotConnectSiteError(preSets.siteUrl, {
|
||||
|
|
|
@ -17,6 +17,62 @@
|
|||
*/
|
||||
export class CoreArray {
|
||||
|
||||
// Avoid creating singleton instances.
|
||||
private constructor() {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of objects to an object, using a property of each entry as the key.
|
||||
* It can also be used to convert an array of strings to an object where the keys are the elements of the array.
|
||||
* E.g. [{id: 10, name: 'A'}, {id: 11, name: 'B'}] => {10: {id: 10, name: 'A'}, 11: {id: 11, name: 'B'}}
|
||||
*
|
||||
* @param array The array to convert.
|
||||
* @param propertyName The name of the property to use as the key. If not provided, the whole item will be used.
|
||||
* @param result Object where to put the properties. If not defined, a new object will be created.
|
||||
* @returns The object.
|
||||
*/
|
||||
static toObject<T>(
|
||||
array: T[] = [],
|
||||
propertyName?: string,
|
||||
result: Record<string, T> = {},
|
||||
): Record<string, T> {
|
||||
for (const entry of array) {
|
||||
const key = propertyName ? entry[propertyName] : entry;
|
||||
|
||||
result[key] = entry;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of objects to an indexed array, using a property of each entry as the key.
|
||||
* Every entry will contain an array of the found objects of the property identifier.
|
||||
* E.g. [{id: 10, name: 'A'}, {id: 10, name: 'B'}] => {10: [ {id: 10, name: 'A'}, {id: 10, name: 'B'} ] }
|
||||
*
|
||||
* @param array The array to convert.
|
||||
* @param propertyName The name of the property to use as the key. If not provided, the whole item will be used.
|
||||
* @param result Object where to put the properties. If not defined, a new object will be created.
|
||||
* @returns The object.
|
||||
*/
|
||||
static toObjectMultiple<T>(
|
||||
array: T[] = [],
|
||||
propertyName?: string,
|
||||
result: Record<string, T[]> = {},
|
||||
): Record<string, T[]> {
|
||||
for (const entry of array) {
|
||||
const key = propertyName ? entry[propertyName] : entry;
|
||||
if (result[key] === undefined) {
|
||||
result[key] = [];
|
||||
}
|
||||
|
||||
result[key].push(entry);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten the first dimension of a multi-dimensional array.
|
||||
*
|
||||
|
@ -93,4 +149,40 @@ export class CoreArray {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge two arrays, removing duplicate values.
|
||||
*
|
||||
* @param array1 The first array.
|
||||
* @param array2 The second array.
|
||||
* @param [key] Key of the property that must be unique. If not specified, the whole entry.
|
||||
* @returns Merged array.
|
||||
*/
|
||||
static mergeWithoutDuplicates<T>(array1: T[], array2: T[], key?: string): T[] {
|
||||
return CoreArray.unique(array1.concat(array2), key) as T[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the first string that matches a regular expression.
|
||||
*
|
||||
* @param array Array to search.
|
||||
* @param regex RegExp to apply to each string.
|
||||
* @returns Index of the first string that matches the RegExp. -1 if not found.
|
||||
*/
|
||||
static indexOfRegexp(array: string[], regex: RegExp): number {
|
||||
if (!array || !array.length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const entry = array[i];
|
||||
const matches = entry.match(regex);
|
||||
|
||||
if (matches && matches.length) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ export class CoreFileUtils {
|
|||
*/
|
||||
static 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 &&
|
||||
return !!(file && typeof file === 'object' && 'isFile' in file && 'filesystem' in file &&
|
||||
'toInternalURL' in file && 'copyTo' in file);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,11 @@ export type CoreObjectWithoutUndefined<T> = Pretty<{
|
|||
*/
|
||||
export class CoreObject {
|
||||
|
||||
// Avoid creating singleton instances.
|
||||
private constructor() {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value of an object and deletes it from the object.
|
||||
*
|
||||
|
@ -170,4 +175,335 @@ export class CoreObject {
|
|||
return cleanObj as CoreObjectWithoutUndefined<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see whether two arrays or objects have the same value at a particular key.
|
||||
* Missing values are replaced by '', and the values are compared with ===.
|
||||
* Booleans and numbers are cast to string before comparing.
|
||||
*
|
||||
* @param obj1 The first object or array.
|
||||
* @param obj2 The second object or array.
|
||||
* @param key Key to check.
|
||||
* @returns Whether the two objects/arrays have the same value (or lack of one) for a given key.
|
||||
*/
|
||||
static sameAtKeyMissingIsBlank(
|
||||
obj1: Record<string, unknown> | unknown[],
|
||||
obj2: Record<string, unknown> | unknown[],
|
||||
key: string,
|
||||
): boolean {
|
||||
let value1 = obj1[key] !== undefined ? obj1[key] : '';
|
||||
let value2 = obj2[key] !== undefined ? obj2[key] : '';
|
||||
|
||||
if (typeof value1 == 'number' || typeof value1 == 'boolean') {
|
||||
value1 = '' + value1;
|
||||
}
|
||||
if (typeof value2 == 'number' || typeof value2 == 'boolean') {
|
||||
value2 = '' + value2;
|
||||
}
|
||||
|
||||
return value1 === value2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stringify an object, sorting the properties. It doesn't sort arrays, only object properties. E.g.:
|
||||
* {b: 2, a: 1} -> '{"a":1,"b":2}'
|
||||
*
|
||||
* @param obj Object to stringify.
|
||||
* @returns Stringified object.
|
||||
*/
|
||||
static sortAndStringify(obj: Record<string, unknown>): string {
|
||||
return JSON.stringify(CoreObject.sortProperties(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an object, sort its properties and the properties of all the nested objects.
|
||||
*
|
||||
* @param obj The object to sort. If it isn't an object, the original value will be returned.
|
||||
* @returns Sorted object.
|
||||
*/
|
||||
static sortProperties<T>(obj: T): T {
|
||||
if (obj != null && typeof obj === 'object' && !Array.isArray(obj)) {
|
||||
// It's an object, sort it.
|
||||
return Object.keys(obj).sort().reduce((accumulator, key) => {
|
||||
// Always call sort with the value. If it isn't an object, the original value will be returned.
|
||||
accumulator[key] = CoreObject.sortProperties(obj[key]);
|
||||
|
||||
return accumulator;
|
||||
}, {} as T);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an object, sort its values. Values need to be primitive values, it cannot have subobjects.
|
||||
*
|
||||
* @param obj The object to sort. If it isn't an object, the original value will be returned.
|
||||
* @returns Sorted object.
|
||||
*/
|
||||
static sortValues<T>(obj: T): T {
|
||||
if (typeof obj === 'object' && !Array.isArray(obj)) {
|
||||
// It's an object, sort it. Convert it to an array to be able to sort it and then convert it back to object.
|
||||
const array = CoreObject.toArrayOfObjects(obj as Record<string, unknown>, 'name', 'value', false, true);
|
||||
|
||||
return CoreObject.toKeyValueMap(array, 'name', 'value') as unknown as T;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an object into an array, losing the keys.
|
||||
*
|
||||
* @param obj Object to convert.
|
||||
* @returns Array with the values of the object but losing the keys.
|
||||
*/
|
||||
static toArray<T>(obj: Record<string, T>): T[] {
|
||||
return Object.keys(obj).map((key) => obj[key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an object into an array of objects, where each entry is an object containing
|
||||
* the key and value of the original object.
|
||||
* For example, it can convert {size: 2} into [{name: 'size', value: 2}].
|
||||
*
|
||||
* @param obj Object to convert.
|
||||
* @param keyName Name of the properties where to store the keys.
|
||||
* @param valueName Name of the properties where to store the values.
|
||||
* @param sortByKey True to sort keys alphabetically, false otherwise. Has priority over sortByValue.
|
||||
* @param sortByValue True to sort values alphabetically, false otherwise.
|
||||
* @returns Array of objects with the name & value of each property.
|
||||
*/
|
||||
static toArrayOfObjects<
|
||||
A extends Record<string,unknown> = Record<string, unknown>,
|
||||
O extends Record<string, unknown> = Record<string, unknown>
|
||||
>(
|
||||
obj: O,
|
||||
keyName: string,
|
||||
valueName: string,
|
||||
sortByKey?: boolean,
|
||||
sortByValue?: boolean,
|
||||
): A[] {
|
||||
// Get the entries from an object or primitive value.
|
||||
const getEntries = (elKey: string, value: unknown): Record<string, unknown>[] | unknown => {
|
||||
if (value === undefined || value == null) {
|
||||
// Filter undefined and null values.
|
||||
return;
|
||||
} else if (CoreObject.isObject(value)) {
|
||||
// It's an object, return at least an entry for each property.
|
||||
const keys = Object.keys(value);
|
||||
let entries: unknown[] = [];
|
||||
|
||||
keys.forEach((key) => {
|
||||
const newElKey = elKey ? elKey + '[' + key + ']' : key;
|
||||
const subEntries = getEntries(newElKey, value[key]);
|
||||
|
||||
if (subEntries) {
|
||||
entries = entries.concat(subEntries);
|
||||
}
|
||||
});
|
||||
|
||||
return entries;
|
||||
} else {
|
||||
// Not an object, return a single entry.
|
||||
const entry = {};
|
||||
entry[keyName] = elKey;
|
||||
entry[valueName] = value;
|
||||
|
||||
return entry;
|
||||
}
|
||||
};
|
||||
|
||||
if (!obj) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// "obj" will always be an object, so "entries" will always be an array.
|
||||
const entries = getEntries('', obj) as A[];
|
||||
if (sortByKey || sortByValue) {
|
||||
return entries.sort((a, b) => {
|
||||
if (sortByKey) {
|
||||
return (a[keyName] as number) >= (b[keyName] as number) ? 1 : -1;
|
||||
} else {
|
||||
return (a[valueName] as number) >= (b[valueName] as number) ? 1 : -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of objects into an object with key and value. The opposite of objectToArrayOfObjects.
|
||||
* For example, it can convert [{name: 'size', value: 2}] into {size: 2}.
|
||||
*
|
||||
* @param objects List of objects to convert.
|
||||
* @param keyName Name of the properties where the keys are stored.
|
||||
* @param valueName Name of the properties where the values are stored.
|
||||
* @param keyPrefix Key prefix if neededs to delete it.
|
||||
* @returns Object.
|
||||
*/
|
||||
static toKeyValueMap<T = unknown>(
|
||||
objects: Record<string, unknown>[],
|
||||
keyName: string,
|
||||
valueName: string,
|
||||
keyPrefix?: string,
|
||||
): {[name: string]: T} {
|
||||
const prefixSubstr = keyPrefix ? keyPrefix.length : 0;
|
||||
const mapped = {};
|
||||
objects.forEach((item) => {
|
||||
const keyValue = item[keyName] as string;
|
||||
const key = prefixSubstr > 0 ? keyValue.substring(prefixSubstr) : keyValue;
|
||||
mapped[key] = item[valueName];
|
||||
});
|
||||
|
||||
return mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an object to a format of GET param. E.g.: {a: 1, b: 2} -> a=1&b=2
|
||||
*
|
||||
* @param object Object to convert.
|
||||
* @param removeEmpty Whether to remove params whose value is null/undefined.
|
||||
* @returns GET params.
|
||||
*/
|
||||
static toGetParams(object: Record<string, unknown>, removeEmpty: boolean = true): string {
|
||||
// First of all, flatten the object so all properties are in the first level.
|
||||
const flattened = CoreObject.flatten(object);
|
||||
let result = '';
|
||||
let joinChar = '';
|
||||
|
||||
for (const name in flattened) {
|
||||
let value = flattened[name];
|
||||
|
||||
if (removeEmpty && (value === null || value === undefined)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof value === 'boolean') {
|
||||
value = value ? 1 : 0;
|
||||
}
|
||||
|
||||
result += joinChar + name + '=' + value;
|
||||
joinChar = '&';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to enumerate enum keys.
|
||||
*
|
||||
* @param enumeration Enumeration object.
|
||||
* @returns Keys of the enumeration.
|
||||
*/
|
||||
static enumKeys<O extends object, K extends keyof O = keyof O>(enumeration: O): K[] {
|
||||
return Object.keys(enumeration).filter(k => Number.isNaN(+k)) as K[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a value is an object.
|
||||
*
|
||||
* @param object Variable.
|
||||
* @returns Type guard indicating if this is an object.
|
||||
*/
|
||||
static isObject(object: unknown): object is Record<string, unknown> {
|
||||
return typeof object === 'object' && object !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten an object, moving subobjects' properties to the first level.
|
||||
* It supports 2 notations: dot notation and square brackets.
|
||||
* E.g.: {a: {b: 1, c: 2}, d: 3} -> {'a.b': 1, 'a.c': 2, d: 3}
|
||||
*
|
||||
* @param obj Object to flatten.
|
||||
* @param useDotNotation Whether to use dot notation '.' or square brackets '['.
|
||||
* @returns Flattened object.
|
||||
*/
|
||||
static flatten(obj: Record<string, unknown>, useDotNotation?: boolean): Record<string, unknown> {
|
||||
const toReturn = {};
|
||||
|
||||
for (const name in obj) {
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const value = obj[name];
|
||||
if (typeof value === 'object' && !Array.isArray(value)) {
|
||||
const flatObject = CoreObject.flatten(value as Record<string, unknown>);
|
||||
for (const subName in flatObject) {
|
||||
if (!Object.prototype.hasOwnProperty.call(flatObject, subName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const newName = useDotNotation ? name + '.' + subName : name + '[' + subName + ']';
|
||||
toReturn[newName] = flatObject[subName];
|
||||
}
|
||||
} else {
|
||||
toReturn[name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two objects. This function won't compare functions and proto properties, it's a basic compare.
|
||||
* Also, this will only check if itemA's properties are in itemB with same value. This function will still
|
||||
* return true if itemB has more properties than itemA.
|
||||
*
|
||||
* @param itemA First object.
|
||||
* @param itemB Second object.
|
||||
* @param maxLevels Number of levels to reach if 2 objects are compared.
|
||||
* @param level Current deep level (when comparing objects).
|
||||
* @param undefinedIsNull True if undefined is equal to null. Defaults to true.
|
||||
* @returns Whether both items are equal.
|
||||
*/
|
||||
static basicLeftCompare(
|
||||
itemA: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
itemB: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
maxLevels: number = 0,
|
||||
level: number = 0,
|
||||
undefinedIsNull: boolean = true,
|
||||
): boolean {
|
||||
if (typeof itemA == 'function' || typeof itemB == 'function') {
|
||||
return true; // Don't compare functions.
|
||||
}
|
||||
|
||||
if (typeof itemA === 'object' && typeof itemB === 'object') {
|
||||
if (level >= maxLevels) {
|
||||
return true; // Max deep reached.
|
||||
}
|
||||
|
||||
let equal = true;
|
||||
for (const name in itemA) {
|
||||
const value = itemA[name];
|
||||
if (name == '$$hashKey') {
|
||||
// Ignore $$hashKey property since it's a "calculated" property.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!CoreObject.basicLeftCompare(value, itemB[name], maxLevels, level + 1)) {
|
||||
equal = false;
|
||||
}
|
||||
}
|
||||
|
||||
return equal;
|
||||
}
|
||||
|
||||
if (undefinedIsNull && (
|
||||
(itemA === undefined && itemB === null) || (itemA === null && itemB === undefined))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We'll treat "2" and 2 as the same value.
|
||||
const floatA = parseFloat(itemA);
|
||||
const floatB = parseFloat(itemB);
|
||||
|
||||
if (!isNaN(floatA) && !isNaN(floatB)) {
|
||||
return floatA == floatB;
|
||||
}
|
||||
|
||||
return itemA === itemB;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue