Bug 1811935 - Adjust visibility of the resource types available for each migrator / profile pair in the new migration wizard. r=Gijs

This causes the MigrationWizardChild to request the full collection of available
migrators and user profiles, and then based on which resourceTypes those migrators
and user profiles have available, changes the visibility of the checkboxes in the
selection page of the new MigrationWizard component.

Differential Revision: https://phabricator.services.mozilla.com/D167617
This commit is contained in:
Mike Conley
2023-01-24 21:15:03 +00:00
parent b5504bd8f7
commit 2683edea63
12 changed files with 399 additions and 49 deletions

View File

@@ -4,6 +4,16 @@
import { MigrationUtils } from "resource:///modules/MigrationUtils.sys.mjs";
import { E10SUtils } from "resource://gre/modules/E10SUtils.sys.mjs";
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
const lazy = {};
XPCOMUtils.defineLazyGetter(lazy, "gFluentStrings", function() {
return new Localization([
"branding/brand.ftl",
"locales-preview/migrationWizard.ftl",
]);
});
/**
* This class is responsible for communicating with MigrationUtils to do the
@@ -35,26 +45,116 @@ export class MigrationWizardParent extends JSWindowActorParent {
}
if (message.name == "GetAvailableMigrators") {
let availableMigrators = new Map();
let availableMigrators = [];
for (const key of MigrationUtils.availableMigratorKeys) {
try {
let migratorPromise = MigrationUtils.getMigrator(key).catch(
console.error
);
if (migratorPromise) {
availableMigrators.set(key, migratorPromise);
}
} catch (e) {
console.error(`Could not get migrator with key ${key}`);
}
availableMigrators.push(this.#getMigratorAndProfiles(key));
}
// Wait for all getMigrator calls to resolve in parallel
await Promise.all(availableMigrators.values());
// ...and then filter out any that resolved to null.
return Array.from(availableMigrators.keys()).filter(key => {
return availableMigrators.get(key);
});
let results = await Promise.all(availableMigrators);
// Each migrator might give us a single MigratorProfileInstance,
// or an Array of them, so we flatten them out and filter out
// any that ended up going wrong and returning null from the
// #getMigratorAndProfiles call.
return results.flat().filter(result => result);
}
return null;
}
/**
* @typedef {object} MigratorProfileInstance
* An object that describes a single user profile (or the default
* user profile) for a particular migrator.
* @property {string} key
* The unique identification key for a migrator.
* @property {string} displayName
* The display name for the migrator that will be shown to the user
* in the wizard.
* @property {string[]} resourceTypes
* An array of strings, where each string represents a resource type
* that can be imported for this migrator and profile. The strings
* should be one of the key values of
* MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.
*
* Example: ["HISTORY", "FORMDATA", "PASSWORDS", "BOOKMARKS"]
* @property {object|null} profile
* A description of the user profile that the migrator can import.
* @property {string} profile.id
* A unique ID for the user profile.
* @property {string} profile.name
* The display name for the user profile.
*/
/**
* Asynchronously fetches a migrator for a particular key, and then
* also gets any user profiles that exist on for that migrator. Resolves
* to null if something goes wrong getting information about the migrator
* or any of the user profiles.
*
* @param {string} key
* The unique identification key for a migrator.
* @returns {Promise<MigratorProfileInstance[]|null>}
*/
async #getMigratorAndProfiles(key) {
try {
let migrator = await MigrationUtils.getMigrator(key);
if (!migrator) {
return null;
}
let sourceProfiles = await migrator.getSourceProfiles();
if (Array.isArray(sourceProfiles)) {
if (!sourceProfiles.length) {
return null;
}
let result = [];
for (let profile of sourceProfiles) {
result.push(
await this.#serializeMigratorAndProfile(migrator, profile)
);
}
return result;
}
return this.#serializeMigratorAndProfile(migrator, sourceProfiles);
} catch (e) {
console.error(`Could not get migrator with key ${key}`, e);
}
return null;
}
/**
* Asynchronously fetches information about what resource types can be
* migrated for a particular migrator and user profile, and then packages
* the migrator, user profile data, and resource type data into an object
* that can be sent down to the MigrationWizardChild.
*
* @param {MigratorBase} migrator
* A migrator subclass of MigratorBase.
* @param {object|null} profileObj
* The user profile object representing the profile to get information
* about. This object is usually gotten by calling getSourceProfiles on
* the migrator.
* @returns {Promise<MigratorProfileInstance>}
*/
async #serializeMigratorAndProfile(migrator, profileObj) {
let profileMigrationData = await migrator.getMigrateData(profileObj);
let availableResourceTypes = [];
for (let resourceType in MigrationUtils.resourceTypes) {
if (profileMigrationData & MigrationUtils.resourceTypes[resourceType]) {
availableResourceTypes.push(resourceType);
}
}
return {
key: migrator.constructor.key,
displayName: await lazy.gFluentStrings.formatValues([
{
id: migrator.constructor.displayNameL10nID,
},
]),
resourceTypes: availableResourceTypes,
profile: profileObj,
};
}
}