feat(client): ts-migrate editor component (#42285)
* class component to functional component * rename Editor to .tsx * add @types and no-verify changes * init ts with no-verify * refactor: files -> challengeFiles * prop-types built from GraphQL * Editor: halfway through 💪 * editor: almost done 🚀 * post-meeting changes with errors * fix: remove chord keybindings * Revert "refactor: files -> challengeFiles" * fix tests type, fix editor bug * fix linting issues * re-add Loadable * kebab-case editor * remove Range import * format package and prop-types * update Show and prop-types * fix: editor background color Co-authored-by: Tom <20648924+moT01@users.noreply.github.com>
This commit is contained in:
committed by
Mrugesh Mohapatra
parent
de261a2b58
commit
36ad0dbcc5
2
client/package-lock.json
generated
2
client/package-lock.json
generated
@ -21661,4 +21661,4 @@
|
|||||||
"integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw=="
|
"integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -160,4 +160,4 @@
|
|||||||
"webpack": "5.40.0",
|
"webpack": "5.40.0",
|
||||||
"webpack-cli": "4.7.2"
|
"webpack-cli": "4.7.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -143,11 +143,30 @@ export type CurrentCertType = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type MarkdownRemarkType = {
|
export type MarkdownRemarkType = {
|
||||||
html: string;
|
fields: [{ component: string; nodeIdentity: string; slug: string }];
|
||||||
|
fileAbsolutePath: string;
|
||||||
frontmatter: {
|
frontmatter: {
|
||||||
title: string;
|
|
||||||
block: string;
|
block: string;
|
||||||
|
isBeta: boolean;
|
||||||
superBlock: string;
|
superBlock: string;
|
||||||
|
title: string;
|
||||||
|
};
|
||||||
|
headings: [
|
||||||
|
{
|
||||||
|
depth: number;
|
||||||
|
value: string;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
html: string;
|
||||||
|
htmlAst: Record<string, unknown>;
|
||||||
|
id: string;
|
||||||
|
rawMarkdownBody: string;
|
||||||
|
timeToRead: number;
|
||||||
|
wordCount: {
|
||||||
|
paragraphs: number;
|
||||||
|
sentences: number;
|
||||||
|
words: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
export type ChallengeNodeType = {
|
export type ChallengeNodeType = {
|
||||||
@ -162,7 +181,7 @@ export type ChallengeNodeType = {
|
|||||||
blockName: string;
|
blockName: string;
|
||||||
tests: TestType[];
|
tests: TestType[];
|
||||||
};
|
};
|
||||||
files: ChallengeFilesType;
|
files: ChallengeFileType;
|
||||||
forumTopicId: number;
|
forumTopicId: number;
|
||||||
guideUrl: string;
|
guideUrl: string;
|
||||||
head: string[];
|
head: string[];
|
||||||
@ -226,6 +245,8 @@ export type DimensionsType = {
|
|||||||
export type TestType = {
|
export type TestType = {
|
||||||
text: string;
|
text: string;
|
||||||
testString: string;
|
testString: string;
|
||||||
|
pass?: boolean;
|
||||||
|
err?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UserType = {
|
export type UserType = {
|
||||||
@ -283,24 +304,24 @@ export type CompletedChallenge = {
|
|||||||
githubLink?: string;
|
githubLink?: string;
|
||||||
challengeType?: number;
|
challengeType?: number;
|
||||||
completedDate: number;
|
completedDate: number;
|
||||||
challengeFiles: ChallengeFileType[];
|
challengeFiles: ChallengeFileType[] | null;
|
||||||
};
|
};
|
||||||
// TODO: renames: files => challengeFiles; key => fileKey; #42489
|
// TODO: renames: files => challengeFiles; key => fileKey; #42489
|
||||||
export type ChallengeFileType = {
|
export type ChallengeFileType =
|
||||||
contents: string;
|
| {
|
||||||
editableContents?: string;
|
[T in FileKeyTypes]:
|
||||||
editableRegionBoundaries?: number[] | null;
|
| ({
|
||||||
error?: string | null;
|
editableContents: string;
|
||||||
ext: ExtTypes;
|
editableRegionBoundaries: number[];
|
||||||
head?: string[];
|
error?: string | null;
|
||||||
history?: string[];
|
history: string[];
|
||||||
fileKey: FileKeyTypes;
|
path: string;
|
||||||
name: string;
|
seed: string;
|
||||||
path: string;
|
seedEditableRegionBoundaries?: number[];
|
||||||
seed?: string;
|
} & FileKeyChallengeType)
|
||||||
seedEditableRegionBoundaries?: number[];
|
| null;
|
||||||
tail?: string;
|
}
|
||||||
};
|
| Record<string, never>;
|
||||||
|
|
||||||
export type ExtTypes = 'js' | 'html' | 'css' | 'jsx';
|
export type ExtTypes = 'js' | 'html' | 'css' | 'jsx';
|
||||||
export type FileKeyTypes = 'indexjs' | 'indexhtml' | 'indexcss';
|
export type FileKeyTypes = 'indexjs' | 'indexhtml' | 'indexcss';
|
||||||
@ -335,28 +356,57 @@ export type PortfolioType = {
|
|||||||
description?: string;
|
description?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type FileKeyChallengeType = {
|
||||||
|
contents: string;
|
||||||
|
ext: ExtTypes;
|
||||||
|
head: string;
|
||||||
|
id: string;
|
||||||
|
key: FileKeyTypes;
|
||||||
|
name: string;
|
||||||
|
tail: string;
|
||||||
|
};
|
||||||
|
|
||||||
// This looks redundant - same as ChallengeNodeType above?
|
// This looks redundant - same as ChallengeNodeType above?
|
||||||
|
// TODO: @moT01 Yes, it is an almost duplicate because @ojeytonwilliams
|
||||||
|
// does not allow us to add 'Type' at the end...
|
||||||
|
// The below is more accurate, because it was built based on graphql's
|
||||||
|
// interpretation of what we have. The props commented out are what we
|
||||||
|
// think are on the node, but actually do not exist.
|
||||||
export type ChallengeNode = {
|
export type ChallengeNode = {
|
||||||
block: string;
|
block: string;
|
||||||
|
challengeFiles: ChallengeFileType;
|
||||||
challengeOrder: number;
|
challengeOrder: number;
|
||||||
challengeType: number;
|
challengeType: number;
|
||||||
dashedName: string;
|
dashedName: string;
|
||||||
description: string;
|
description: string;
|
||||||
challengeFiles: ChallengeFileType;
|
|
||||||
fields: {
|
fields: {
|
||||||
slug: string;
|
slug: string;
|
||||||
blockName: string;
|
blockName: string;
|
||||||
|
tests: TestType[];
|
||||||
};
|
};
|
||||||
forumTopicId: number;
|
forumTopicId: number;
|
||||||
guideUrl: string;
|
// guideUrl: string;
|
||||||
head: string[];
|
// head: string[];
|
||||||
helpCategory: string;
|
helpCategory: string;
|
||||||
|
id: string;
|
||||||
instructions: string;
|
instructions: string;
|
||||||
isComingSoon: boolean;
|
internal?: {
|
||||||
removeComments: boolean;
|
content: string;
|
||||||
isLocked: boolean;
|
contentDigest: string;
|
||||||
isPrivate: boolean;
|
description: string;
|
||||||
|
fieldOwners: string[];
|
||||||
|
ignoreType: boolean | null;
|
||||||
|
mediaType: string;
|
||||||
|
owner: string;
|
||||||
|
type: string;
|
||||||
|
};
|
||||||
order: number;
|
order: number;
|
||||||
|
question: {
|
||||||
|
answers: string[];
|
||||||
|
solution: number;
|
||||||
|
text: string;
|
||||||
|
} | null;
|
||||||
|
removeComments: boolean;
|
||||||
required: [
|
required: [
|
||||||
{
|
{
|
||||||
link: string;
|
link: string;
|
||||||
@ -364,11 +414,21 @@ export type ChallengeNode = {
|
|||||||
src: string;
|
src: string;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
superOrder: number;
|
solutions: {
|
||||||
|
[T in FileKeyTypes]: FileKeyChallengeType;
|
||||||
|
};
|
||||||
|
sourceInstanceName: string;
|
||||||
superBlock: string;
|
superBlock: string;
|
||||||
tail: string[];
|
superOrder: number;
|
||||||
|
template: string;
|
||||||
|
tests: TestType[];
|
||||||
time: string;
|
time: string;
|
||||||
title: string;
|
title: string;
|
||||||
translationPending: boolean;
|
translationPending: boolean;
|
||||||
|
videoId?: string;
|
||||||
videoUrl?: string;
|
videoUrl?: string;
|
||||||
|
// isComingSoon: boolean;
|
||||||
|
// isLocked: boolean;
|
||||||
|
// isPrivate: boolean;
|
||||||
|
// tail: string[];
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@ import {
|
|||||||
updateFile
|
updateFile
|
||||||
} from '../redux';
|
} from '../redux';
|
||||||
import './editor.css';
|
import './editor.css';
|
||||||
import Editor from './Editor';
|
import Editor from './editor';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
canFocus: PropTypes.bool,
|
canFocus: PropTypes.bool,
|
||||||
|
@ -30,7 +30,7 @@ import { challengeTypes } from '../../../../utils/challengeTypes';
|
|||||||
import { isContained } from '../../../utils/is-contained';
|
import { isContained } from '../../../utils/is-contained';
|
||||||
import {
|
import {
|
||||||
ChallengeNodeType,
|
ChallengeNodeType,
|
||||||
ChallengeFilesType,
|
ChallengeFileType,
|
||||||
ChallengeMetaType,
|
ChallengeMetaType,
|
||||||
TestType,
|
TestType,
|
||||||
ResizePropsType
|
ResizePropsType
|
||||||
@ -77,10 +77,10 @@ const mapDispatchToProps = (dispatch: Dispatch) =>
|
|||||||
interface ShowClassicProps {
|
interface ShowClassicProps {
|
||||||
cancelTests: () => void;
|
cancelTests: () => void;
|
||||||
challengeMounted: (arg0: string) => void;
|
challengeMounted: (arg0: string) => void;
|
||||||
createFiles: (arg0: ChallengeFilesType) => void;
|
createFiles: (arg0: ChallengeFileType) => void;
|
||||||
data: { challengeNode: ChallengeNodeType };
|
data: { challengeNode: ChallengeNodeType };
|
||||||
executeChallenge: () => void;
|
executeChallenge: () => void;
|
||||||
files: ChallengeFilesType;
|
files: ChallengeFileType;
|
||||||
initConsole: (arg0: string) => void;
|
initConsole: (arg0: string) => void;
|
||||||
initTests: (tests: TestType[]) => void;
|
initTests: (tests: TestType[]) => void;
|
||||||
output: string[];
|
output: string[];
|
||||||
@ -329,7 +329,7 @@ class ShowClassic extends Component<ShowClassicProps, ShowClassicState> {
|
|||||||
const { files } = this.props;
|
const { files } = this.props;
|
||||||
return Object.values(files).some(
|
return Object.values(files).some(
|
||||||
file =>
|
file =>
|
||||||
file.editableRegionBoundaries &&
|
file?.editableRegionBoundaries &&
|
||||||
file.editableRegionBoundaries.length === 2
|
file.editableRegionBoundaries.length === 2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
1166
client/src/templates/Challenges/classic/editor.tsx
Normal file
1166
client/src/templates/Challenges/classic/editor.tsx
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user