Skip to content

Commit 1c12d4f

Browse files
committed
fix: code review
1 parent 043f5e6 commit 1c12d4f

File tree

7 files changed

+87
-37
lines changed

7 files changed

+87
-37
lines changed

extensions/vscode/src/commands/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as vscode from 'vscode';
22
import { addChapter, addLesson, addPart } from './tutorialkit.add';
3-
import { deleteUnit } from './tutorialkit.delete';
3+
import { deleteNode } from './tutorialkit.delete';
44
import tutorialkitGoto from './tutorialkit.goto';
55
import { initialize } from './tutorialkit.initialize';
66
import { loadTutorial } from './tutorialkit.load-tutorial';
@@ -29,7 +29,7 @@ export function useCommands() {
2929
vscode.commands.registerCommand(CMD.ADD_LESSON, addLesson);
3030
vscode.commands.registerCommand(CMD.ADD_CHAPTER, addChapter);
3131
vscode.commands.registerCommand(CMD.ADD_PART, addPart);
32-
vscode.commands.registerCommand(CMD.DELETE, deleteUnit);
32+
vscode.commands.registerCommand(CMD.DELETE, deleteNode);
3333
vscode.commands.registerCommand(CMD.REFRESH, tutorialkitRefresh);
3434
}
3535

@@ -39,7 +39,7 @@ export const cmd = {
3939
selectTutorial: createExecutor<typeof selectTutorial>(CMD.SELECT_TUTORIAL),
4040
loadTutorial: createExecutor<typeof loadTutorial>(CMD.LOAD_TUTORIAL),
4141
goto: createExecutor<typeof tutorialkitGoto>(CMD.GOTO),
42-
delete: createExecutor<typeof deleteUnit>(CMD.DELETE),
42+
delete: createExecutor<typeof deleteNode>(CMD.DELETE),
4343
addLesson: createExecutor<typeof addLesson>(CMD.ADD_LESSON),
4444
addPart: createExecutor<typeof addPart>(CMD.ADD_PART),
4545
addChapter: createExecutor<typeof addChapter>(CMD.ADD_CHAPTER),

extensions/vscode/src/commands/tutorialkit.add.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ let capitalize: (string: string) => string;
1414
})();
1515

1616
export async function addLesson(parent: Node) {
17-
const { folderPath, metaFilePath } = await createUnitFolder(parent, 'lesson');
17+
const { folderPath, metaFilePath } = await createNodeFolder(parent, 'lesson');
1818

1919
await vscode.workspace.fs.createDirectory(vscode.Uri.joinPath(folderPath, FILES_FOLDER));
2020
await vscode.workspace.fs.createDirectory(vscode.Uri.joinPath(folderPath, SOLUTION_FOLDER));
@@ -25,22 +25,22 @@ export async function addLesson(parent: Node) {
2525
}
2626

2727
export async function addChapter(parent: Node) {
28-
const { metaFilePath } = await createUnitFolder(parent, 'chapter');
28+
const { metaFilePath } = await createNodeFolder(parent, 'chapter');
2929

3030
await cmd.refresh();
3131

3232
return cmd.goto(metaFilePath);
3333
}
3434

3535
export async function addPart(parent: Node) {
36-
const { metaFilePath } = await createUnitFolder(parent, 'part');
36+
const { metaFilePath } = await createNodeFolder(parent, 'part');
3737

3838
await cmd.refresh();
3939

4040
return cmd.goto(metaFilePath);
4141
}
4242

43-
async function getUnitName(unitType: NodeType, unitNumber: number) {
43+
async function getNodeName(unitType: NodeType, unitNumber: number) {
4444
const unitName = await vscode.window.showInputBox({
4545
prompt: `Enter the name of the new ${unitType}`,
4646
value: `${capitalize(unitType)} ${unitNumber}`,
@@ -54,12 +54,12 @@ async function getUnitName(unitType: NodeType, unitNumber: number) {
5454
return unitName;
5555
}
5656

57-
async function createUnitFolder(parent: Node, unitType: NodeType) {
57+
async function createNodeFolder(parent: Node, nodeType: NodeType) {
5858
const unitNumber = parent.children.length + 1;
59-
const unitName = await getUnitName(unitType, unitNumber);
59+
const unitName = await getNodeName(nodeType, unitNumber);
6060
const unitFolderPath = parent.order ? kebabCase(unitName) : `${unitNumber}-${kebabCase(unitName)}`;
6161

62-
const metaFile = unitType === 'lesson' ? 'content.mdx' : 'meta.md';
62+
const metaFile = nodeType === 'lesson' ? 'content.mdx' : 'meta.md';
6363
const metaFilePath = vscode.Uri.joinPath(parent.path, unitFolderPath, metaFile);
6464

6565
if (parent.order) {
@@ -69,7 +69,7 @@ async function createUnitFolder(parent: Node, unitType: NodeType) {
6969

7070
await vscode.workspace.fs.writeFile(
7171
metaFilePath,
72-
new TextEncoder().encode(`---\ntype: ${unitType}\ntitle: ${unitName}\n---\n`),
72+
new TextEncoder().encode(`---\ntype: ${nodeType}\ntitle: ${unitName}\n---\n`),
7373
);
7474

7575
return {

extensions/vscode/src/commands/tutorialkit.delete.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,34 @@ import { cmd } from '.';
22
import * as vscode from 'vscode';
33
import { Node } from '../models/Node';
44
import { getLessonsTreeView } from '../global-state';
5+
import { updateNodeMetadataInVFS } from '../models/tree/update';
56

6-
export async function deleteUnit(selectedNode: Node | undefined, selectedNodes: Node[] | undefined) {
7+
export async function deleteNode(selectedNode: Node | undefined, selectedNodes: Node[] | undefined) {
78
let nodes: readonly Node[] = (selectedNodes ? selectedNodes : [selectedNode]).filter((node) => node !== undefined);
89

910
if (nodes.length === 0) {
1011
nodes = getLessonsTreeView().selection;
1112
}
1213

14+
const parents = new Set<Node>();
15+
1316
for (const node of nodes) {
17+
if (node.parent) {
18+
parents.add(node.parent);
19+
node.parent.removeChild(node);
20+
}
21+
1422
await vscode.workspace.fs.delete(node.path, { recursive: true });
1523
}
1624

25+
// remove all nodes from parents that that might have been parent of other deleted nodes
26+
for (const node of nodes) {
27+
parents.delete(node);
28+
}
29+
30+
for (const parent of parents) {
31+
await updateNodeMetadataInVFS(parent);
32+
}
33+
1734
return cmd.refresh();
1835
}

extensions/vscode/src/commands/tutorialkit.goto.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export default async (path: string | vscode.Uri | undefined) => {
1616
* ;
1717
* ```
1818
*
19-
* Type check correctly despite doing nothing different on each branch.
19+
* Type check correctly despite being identical to calling the function
20+
* without the branch.
2021
*
2122
* To avoid this TypeScript bug here we just cast to any.
2223
*/

extensions/vscode/src/models/Node.ts

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ export class Node {
2525
*/
2626
children: Node[] = [];
2727

28+
/**
29+
* The parent of that node.
30+
*/
31+
parent?: Node;
32+
2833
/**
2934
* If specified, describe the order of the children.
3035
* When children are loaded, this should be used to sort
@@ -54,30 +59,73 @@ export class Node {
5459
private _customName?: string,
5560
) {}
5661

57-
pushChild(folderPath: string) {
62+
pushChild(folderName: string) {
5863
this.childCount += 1;
5964

6065
if (this.order) {
61-
this.order.set(folderPath, this.order.size);
66+
this.order.set(folderName, this.order.size);
67+
68+
switch (this.metadata?.type) {
69+
case 'chapter': {
70+
this.metadata.lessons!.push(folderName);
71+
break;
72+
}
73+
case 'tutorial': {
74+
this.metadata.parts!.push(folderName);
75+
break;
76+
}
77+
case 'part': {
78+
this.metadata.chapters!.push(folderName);
79+
break;
80+
}
81+
}
82+
}
83+
}
84+
85+
removeChild(node: Node) {
86+
if (!removeFromArray(this.children, node)) {
87+
return;
88+
}
6289

90+
if (this.order) {
6391
switch (this.metadata?.type) {
6492
case 'chapter': {
65-
this.metadata.lessons!.push(folderPath);
93+
removeFromArray(this.metadata.lessons!, node.folderName);
6694
break;
6795
}
6896
case 'tutorial': {
69-
this.metadata.parts!.push(folderPath);
97+
removeFromArray(this.metadata.parts!, node.folderName);
7098
break;
7199
}
72100
case 'part': {
73-
this.metadata.chapters!.push(folderPath);
101+
removeFromArray(this.metadata.chapters!, node.folderName);
74102
break;
75103
}
76104
}
77105
}
78106
}
107+
108+
setChildren(children: Node[]) {
109+
this.children = children;
110+
111+
for (const child of this.children) {
112+
child.parent = this;
113+
}
114+
}
79115
}
80116

81117
export type Metadata = PartSchema | ChapterSchema | LessonSchema | TutorialSchema;
82118

83119
export type NodeType = Metadata['type'];
120+
121+
function removeFromArray<T>(array: T[], element: T) {
122+
const index = array.indexOf(element);
123+
124+
if (index != -1) {
125+
array.splice(index, 1);
126+
127+
return true;
128+
}
129+
130+
return false;
131+
}

extensions/vscode/src/models/tree/load.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as vscode from 'vscode';
22
import grayMatter from 'gray-matter';
33
import { Metadata, Node } from '../Node';
44
import { METADATA_FILES, FILES_FOLDER, SOLUTION_FOLDER } from './constants';
5-
import { uriDirname } from '../../utils/uri';
5+
import { Utils } from 'vscode-uri';
66

77
export async function loadTutorialTree(tutorialFolderPath: vscode.Uri, tutorialName: string): Promise<Node> {
88
const metaFilePath = vscode.Uri.joinPath(tutorialFolderPath, 'meta.md');
@@ -23,7 +23,7 @@ export async function loadChildrenForNode(node: Node) {
2323
return;
2424
}
2525

26-
node.children = await loadTutorialTreeFromBaseFolder(node.path);
26+
node.setChildren(await loadTutorialTreeFromBaseFolder(node.path));
2727

2828
// sort children based on their order if defined in the metadata
2929
const order = node.order;
@@ -83,7 +83,7 @@ async function loadTutorialTreeFromBaseFolder(baseFolderPath: vscode.Uri): Promi
8383
}
8484

8585
async function updateNodeFromMetadata(node: Node, metadataFilePath: vscode.Uri) {
86-
const folderPath = uriDirname(metadataFilePath);
86+
const folderPath = Utils.dirname(metadataFilePath);
8787
const metadataFileContent = await readFileContent(metadataFilePath);
8888
const parsedContent = grayMatter(metadataFileContent);
8989

extensions/vscode/src/utils/uri.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)