mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-01 13:47:06 +01:00
3c622cd395
If you're thinking about converting a file to TypeScript, you might want to know what files import that file and what files it imports. This commit makes it so that if you click on a box in the visualization, it will draw lines between that box and the other boxes which represent its dependents and dependencies. Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com>
218 lines
7.5 KiB
TypeScript
218 lines
7.5 KiB
TypeScript
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<Record<string, ModulePartitionChild>>(
|
|
(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<Record<
|
|
string,
|
|
BoxRect
|
|
> | null>(null);
|
|
const boxesByModuleId =
|
|
boxRectsByModuleId === null
|
|
? {}
|
|
: Object.values(boxRectsByModuleId).reduce<Record<string, BoxModel>>(
|
|
(obj, boxRect) => {
|
|
const module = modulesById[boxRect.moduleId];
|
|
|
|
const dependencyBoxRects = module.dependencyIds.reduce<BoxRect[]>(
|
|
(dependencyBoxes, dependencyId) => {
|
|
if (boxRectsByModuleId[dependencyId] === undefined) {
|
|
return dependencyBoxes;
|
|
}
|
|
return [...dependencyBoxes, boxRectsByModuleId[dependencyId]];
|
|
},
|
|
[],
|
|
);
|
|
|
|
const dependentBoxRects = module.dependentIds.reduce<BoxRect[]>(
|
|
(dependentBoxes, dependentId) => {
|
|
if (boxRectsByModuleId[dependentId] === undefined) {
|
|
return dependentBoxes;
|
|
}
|
|
return [...dependentBoxes, boxRectsByModuleId[dependentId]];
|
|
},
|
|
[],
|
|
);
|
|
|
|
return {
|
|
...obj,
|
|
[boxRect.moduleId]: {
|
|
rect: boxRect,
|
|
dependencyBoxRects,
|
|
dependentBoxRects,
|
|
},
|
|
};
|
|
},
|
|
{},
|
|
);
|
|
const [activeBoxRectId, setActiveBoxRectId] = useState<string | null>(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 (
|
|
<>
|
|
<h1 className="page-header">
|
|
<img src="images/metamask-fox.svg" className="page-header__icon" />
|
|
Extension TypeScript Migration Status
|
|
</h1>
|
|
<h2
|
|
className="overall-summary"
|
|
style={{
|
|
'--progress': `${calculatePercentageComplete(overallTotal)}%`,
|
|
}}
|
|
>
|
|
OVERALL: {overallTotal.numConvertedModules}/{overallTotal.numModules} (
|
|
{calculatePercentageComplete(overallTotal)}%)
|
|
</h2>
|
|
<details className="help">
|
|
<summary className="help__question">What is this?</summary>
|
|
<div className="help__answer">
|
|
<p>
|
|
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.
|
|
</p>
|
|
|
|
<p>
|
|
Each box on this page represents a file in the codebase. Gray boxes
|
|
<span className="module module--inline module--to-be-converted">
|
|
|
|
</span>
|
|
represent files that need to be converted to TypeScript. Green boxes
|
|
<span className="module module--inline module--has-been-converted">
|
|
|
|
</span>
|
|
are files that have already been converted. Faded boxes
|
|
<span className="module module--inline module--to-be-converted module--test">
|
|
|
|
</span>
|
|
<span
|
|
className="module module--inline module--has-been-converted module--test"
|
|
style={{ marginLeft: 0 }}
|
|
>
|
|
|
|
</span>
|
|
are test or Storybook files.
|
|
</p>
|
|
|
|
<p>
|
|
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;{' '}
|
|
<strong className="module-connection__dependency">red</strong> lines
|
|
lead to dependencies (other files that import the file);{' '}
|
|
<strong className="module-connection__dependent">blue</strong> lines
|
|
lead to dependents (other files that are imported by the file).
|
|
</p>
|
|
|
|
<p>
|
|
These boxes are further partitioned by <em>level</em>. 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{' '}
|
|
<code>foo.js</code>, and that file imports <code>bar.js</code> and{' '}
|
|
<code>baz.js</code>, and <code>baz.js</code> imports{' '}
|
|
<code>qux.js</code>, then:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>
|
|
<code>foo.js</code> would be at <em>level 1</em>
|
|
</li>
|
|
<li>
|
|
<code>bar.js</code> and <code>baz.js</code> would be at{' '}
|
|
<em>level 2</em>
|
|
</li>
|
|
<li>
|
|
<code>qux.js</code> would be at <em>level 3</em>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
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,{' '}
|
|
<strong>
|
|
you should be able to start from the top and go down
|
|
</strong>
|
|
.
|
|
</p>
|
|
</div>
|
|
</details>
|
|
<div className="partitions">
|
|
{partitions.map((partition) => {
|
|
return (
|
|
<div key={partition.level} className="partition">
|
|
<div className="partition__name">level {partition.level}</div>
|
|
<div className="partition__children">
|
|
{partition.children.map((module) => {
|
|
const areConnectionsVisible = activeBoxRectId === module.id;
|
|
return (
|
|
<Box
|
|
key={module.id}
|
|
module={module}
|
|
register={registerBox}
|
|
toggleConnectionsFor={toggleConnectionsFor}
|
|
areConnectionsVisible={areConnectionsVisible}
|
|
/>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
{activeBoxRect === null ? null : (
|
|
<Connections activeBox={boxesByModuleId[activeBoxRect.moduleId]} />
|
|
)}
|
|
</div>
|
|
</>
|
|
);
|
|
}
|