diff --git a/src/libs/migrations/RemoveEmptyReportActionsDrafts.js b/src/libs/migrations/RemoveEmptyReportActionsDrafts.js deleted file mode 100644 index 586cca8ca1ed..000000000000 --- a/src/libs/migrations/RemoveEmptyReportActionsDrafts.js +++ /dev/null @@ -1,69 +0,0 @@ -import Onyx from 'react-native-onyx'; -import _ from 'underscore'; -import Log from '@libs/Log'; -import ONYXKEYS from '@src/ONYXKEYS'; - -/** - * This migration removes empty drafts from reportActionsDrafts, which was previously used to mark a draft as being non-existent (e.g. upon cancel). - * - * @returns {Promise} - */ -export default function () { - return new Promise((resolve) => { - const connectionID = Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS, - waitForCollectionCallback: true, - callback: (allReportActionsDrafts) => { - Onyx.disconnect(connectionID); - - if (!allReportActionsDrafts) { - Log.info('[Migrate Onyx] Skipped migration RemoveEmptyReportActionsDrafts because there were no reportActionsDrafts'); - return resolve(); - } - - const newReportActionsDrafts = {}; - _.each(allReportActionsDrafts, (reportActionDrafts, onyxKey) => { - newReportActionsDrafts[onyxKey] = {}; - - // Whether there is at least one draft in this report that has to be migrated - let hasUnmigratedDraft = false; - - _.each(reportActionDrafts, (reportActionDraft, reportActionID) => { - // If the draft is a string, it means it hasn't been migrated yet - if (_.isString(reportActionDraft)) { - hasUnmigratedDraft = true; - Log.info(`[Migrate Onyx] Migrating draft for report action ${reportActionID}`); - - if (_.isEmpty(reportActionDraft)) { - Log.info(`[Migrate Onyx] Removing draft for report action ${reportActionID}`); - return; - } - - newReportActionsDrafts[onyxKey][reportActionID] = {message: reportActionDraft}; - } else { - // We've already migrated this draft, so keep the existing value - newReportActionsDrafts[onyxKey][reportActionID] = reportActionDraft; - } - }); - - if (_.isEmpty(newReportActionsDrafts[onyxKey])) { - // Clear if there are no drafts remaining - newReportActionsDrafts[onyxKey] = null; - } else if (!hasUnmigratedDraft) { - // All drafts for this report have already been migrated, there's no need to overwrite this onyx key with the same data - delete newReportActionsDrafts[onyxKey]; - } - }); - - if (_.isEmpty(newReportActionsDrafts)) { - Log.info('[Migrate Onyx] Skipped migration RemoveEmptyReportActionsDrafts because there are no actions drafts to migrate'); - return resolve(); - } - - Log.info(`[Migrate Onyx] Ran migration RemoveEmptyReportActionsDrafts and updated drafts for ${_.keys(newReportActionsDrafts).length} reports`); - // eslint-disable-next-line rulesdir/prefer-actions-set-data - return Onyx.multiSet(newReportActionsDrafts).then(resolve); - }, - }); - }); -} diff --git a/src/libs/migrations/RemoveEmptyReportActionsDrafts.ts b/src/libs/migrations/RemoveEmptyReportActionsDrafts.ts new file mode 100644 index 000000000000..d8816198e537 --- /dev/null +++ b/src/libs/migrations/RemoveEmptyReportActionsDrafts.ts @@ -0,0 +1,76 @@ +import _ from 'lodash'; +import Onyx, {OnyxEntry} from 'react-native-onyx'; +import Log from '@libs/Log'; +import ONYXKEYS from '@src/ONYXKEYS'; +import {ReportActionsDraft, ReportActionsDrafts} from '@src/types/onyx'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; + +type ReportActionsDraftsKey = `${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${string}`; + +/** + * This migration removes empty drafts from reportActionsDrafts, which was previously used to mark a draft as being non-existent (e.g. upon cancel). + */ +export default function (): Promise { + return new Promise((resolve) => { + const connectionID = Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS, + waitForCollectionCallback: true, + callback: (allReportActionsDrafts) => { + Onyx.disconnect(connectionID); + + if (!allReportActionsDrafts) { + Log.info('[Migrate Onyx] Skipped migration RemoveEmptyReportActionsDrafts because there were no reportActionsDrafts'); + return resolve(); + } + + const newReportActionsDrafts: Record> = {}; + Object.entries(allReportActionsDrafts).forEach(([onyxKey, reportActionDrafts]) => { + const newReportActionsDraftsForReport: Record = {}; + + // Whether there is at least one draft in this report that has to be migrated + let hasUnmigratedDraft = false; + + if (reportActionDrafts) { + Object.entries(reportActionDrafts).forEach(([reportActionID, reportActionDraft]) => { + // If the draft is a string, it means it hasn't been migrated yet + if (typeof reportActionDraft === 'string') { + hasUnmigratedDraft = true; + Log.info(`[Migrate Onyx] Migrating draft for report action ${reportActionID}`); + + if (_.isEmpty(reportActionDraft)) { + Log.info(`[Migrate Onyx] Removing draft for report action ${reportActionID}`); + return; + } + + newReportActionsDraftsForReport[reportActionID] = {message: reportActionDraft}; + } else { + // We've already migrated this draft, so keep the existing value + newReportActionsDraftsForReport[reportActionID] = reportActionDraft; + } + }); + } + + if (isEmptyObject(newReportActionsDraftsForReport)) { + Log.info('[Migrate Onyx] NO REMAINING'); + // Clear if there are no drafts remaining + newReportActionsDrafts[onyxKey as ReportActionsDraftsKey] = null; + } else if (hasUnmigratedDraft) { + // Only migrate if there are unmigrated drafts, there's no need to overwrite this onyx key with the same data + newReportActionsDrafts[onyxKey as ReportActionsDraftsKey] = newReportActionsDraftsForReport; + } + }); + + if (isEmptyObject(newReportActionsDrafts)) { + Log.info('[Migrate Onyx] Skipped migration RemoveEmptyReportActionsDrafts because there are no actions drafts to migrate'); + return resolve(); + } + + Log.info(`[Migrate Onyx] Updating drafts for ${Object.keys(newReportActionsDrafts).length} reports`); + Onyx.multiSet(newReportActionsDrafts).then(() => { + Log.info('[Migrate Onyx] Ran migration RemoveEmptyReportActionsDrafts successfully'); + resolve(); + }); + }, + }); + }); +} diff --git a/src/types/onyx/ReportActionsDraft.ts b/src/types/onyx/ReportActionsDraft.ts new file mode 100644 index 000000000000..41a701f16e71 --- /dev/null +++ b/src/types/onyx/ReportActionsDraft.ts @@ -0,0 +1,7 @@ +type ReportActionsDraft = + | { + message: string; + } + | string; + +export default ReportActionsDraft; diff --git a/src/types/onyx/ReportActionsDrafts.ts b/src/types/onyx/ReportActionsDrafts.ts index 34ccc977ef48..ad2782111144 100644 --- a/src/types/onyx/ReportActionsDrafts.ts +++ b/src/types/onyx/ReportActionsDrafts.ts @@ -1,6 +1,4 @@ -type ReportActionsDraft = { - message: string; -}; +import ReportActionsDraft from './ReportActionsDraft'; type ReportActionsDrafts = Record; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 229fd0a53158..45c47793c458 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -37,6 +37,7 @@ import ReimbursementAccountDraft from './ReimbursementAccountDraft'; import Report from './Report'; import ReportAction, {ReportActions} from './ReportAction'; import ReportActionReactions from './ReportActionReactions'; +import ReportActionsDraft from './ReportActionsDraft'; import ReportActionsDrafts from './ReportActionsDrafts'; import ReportMetadata from './ReportMetadata'; import ReportNextStep from './ReportNextStep'; @@ -107,6 +108,7 @@ export type { ReportAction, ReportActionReactions, ReportActions, + ReportActionsDraft, ReportActionsDrafts, ReportMetadata, ReportNextStep,