import React, { useState } from 'react'; import { readPartitionsFile } from '../../common/partitions-file'; import type { ModulePartitionChild } from '../../common/build-module-partitions'; import Box from './Box'; import Connections from './Connections'; import type { BoxRect, BoxModel } from './types'; type Summary = { numConvertedModules: number; numModules: number; }; function calculatePercentageComplete(summary: Summary) { return ((summary.numConvertedModules / summary.numModules) * 100).toFixed(1); } const partitions = readPartitionsFile(); const allModules = partitions.flatMap((partition) => { return partition.children; }); const modulesById = allModules.reduce>( (obj, module) => { return { ...obj, [module.id]: module }; }, {}, ); const overallTotal = { numConvertedModules: allModules.filter((module) => module.hasBeenConverted) .length, numModules: allModules.length, }; export default function App() { const [boxRectsByModuleId, setBoxRectsById] = useState | null>(null); const boxesByModuleId = boxRectsByModuleId === null ? {} : Object.values(boxRectsByModuleId).reduce>( (obj, boxRect) => { const module = modulesById[boxRect.moduleId]; const dependencyBoxRects = module.dependencyIds.reduce( (dependencyBoxes, dependencyId) => { if (boxRectsByModuleId[dependencyId] === undefined) { return dependencyBoxes; } return [...dependencyBoxes, boxRectsByModuleId[dependencyId]]; }, [], ); const dependentBoxRects = module.dependentIds.reduce( (dependentBoxes, dependentId) => { if (boxRectsByModuleId[dependentId] === undefined) { return dependentBoxes; } return [...dependentBoxes, boxRectsByModuleId[dependentId]]; }, [], ); return { ...obj, [boxRect.moduleId]: { rect: boxRect, dependencyBoxRects, dependentBoxRects, }, }; }, {}, ); const [activeBoxRectId, setActiveBoxRectId] = useState(null); const activeBoxRect = boxRectsByModuleId === null || activeBoxRectId === null ? null : boxRectsByModuleId[activeBoxRectId]; const registerBox = (id: string, boxRect: BoxRect) => { setBoxRectsById((existingBoxRectsById) => { if (existingBoxRectsById === undefined) { return { [id]: boxRect }; } return { ...existingBoxRectsById, [id]: boxRect }; }); }; const toggleConnectionsFor = (id: string) => { if (activeBoxRectId !== undefined && activeBoxRectId === id) { setActiveBoxRectId(null); } else { setActiveBoxRectId(id); } }; return ( <>

Extension TypeScript Migration Status

OVERALL: {overallTotal.numConvertedModules}/{overallTotal.numModules} ( {calculatePercentageComplete(overallTotal)}%)

What is this?

This is a dashboard that tracks the status of converting the extension codebase from JavaScript to TypeScript. It is updated whenever a new commit is pushed to the codebase, so it always represents the current work.

Each box on this page represents a file in the codebase. Gray boxes   represent files that need to be converted to TypeScript. Green boxes   are files that have already been converted. Faded boxes     are test or Storybook files.

You can hover over a box to see the name of the file that it represents. You can also click on a box to see connections between other files;{' '} red lines lead to dependencies (other files that import the file);{' '} blue lines lead to dependents (other files that are imported by the file).

These boxes are further partitioned by level. The level of a file is how many files you have to import before you reach that file in the whole codebase. For instance, if we have a file{' '} foo.js, and that file imports bar.js and{' '} baz.js, and baz.js imports{' '} qux.js, then:

  • foo.js would be at level 1
  • bar.js and baz.js would be at{' '} level 2
  • qux.js would be at level 3

This level assignment can be used to determine a priority for converting the remaining JavaScript files. Files which have fewer dependencies should in theory be easier to convert, so files with a higher level should be converted first. In other words,{' '} you should be able to start from the top and go down .

{partitions.map((partition) => { return (
level {partition.level}
{partition.children.map((module) => { const areConnectionsVisible = activeBoxRectId === module.id; return ( ); })}
); })} {activeBoxRect === null ? null : ( )}
); }