Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: code review
  • Loading branch information
AriPerkkio committed Aug 13, 2024
commit f498eb2a452e300a77e001fd525fce42512e63a8
8 changes: 4 additions & 4 deletions packages/astro/src/default/utils/content.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ChapterSchema, Lesson, LessonSchema, PartSchema, Tutorial, TutorialSchema } from '@tutorialkit/types';
import { interpolateString } from '@tutorialkit/types';
import { getCollection } from 'astro:content';
import mm from 'micromatch';
import micromatch from 'micromatch';
import path from 'node:path';
import { DEFAULT_LOCALIZATION } from './content/default-localization';
import { squash } from './content/squash.js';
Expand Down Expand Up @@ -257,14 +257,14 @@ export async function getTutorial(): Promise<Tutorial> {
};

if (lesson.data.template && typeof lesson.data.template !== 'string' && lesson.data.template.visibleFiles?.length) {
const templateFilesRef = await getFilesRefList(lesson.data.template.name, TEMPLATES_DIR);
const [, tempalteFiles] = await getFilesRefList(lesson.data.template.name, TEMPLATES_DIR);

for (const filename of templateFilesRef[1]) {
for (const filename of tempalteFiles) {
if (lesson.files[1].includes(filename)) {
continue;
}

if (mm.isMatch(filename, lesson.data.template.visibleFiles, { format: formatTemplateFile })) {
if (micromatch.isMatch(filename, lesson.data.template.visibleFiles, { format: formatTemplateFile })) {
lesson.files[1].push(filename);
}
}
Expand Down
14 changes: 11 additions & 3 deletions packages/runtime/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export class TutorialStore {
this._lessonFiles = files;
this._lessonSolution = solution;
this._lessonTemplate = template;
this._visibleTemplateFiles = filterEntries(template, lesson.files[1]);
this._visibleTemplateFiles = pick(template, lesson.files[1]);

const editorFiles = { ...this._visibleTemplateFiles, ...this._lessonFiles };
this._editorStore.setDocuments(editorFiles);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed that the files from the template are not read-only.

Given that they aren't part of the lesson but are here to provide information on the project, I really feel like they should be read only. Otherwise it feels like we're moving too far away from the original goal of having tutorials be this "safe" environment where learners can focus on the learning.

@AriPerkkio AriPerkkio Aug 28, 2024

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have options to make any file readonly at the moment. Maybe we need such feature, especially once adding new files via terminal becomes possible?

Currently it's intentional that files are modifiable. This is simply to reduce repetition - you don't have to copy-paste files in every single lesson just to make them visible.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have options to make any file readonly at the moment. Maybe we need such feature, especially once adding new files via terminal becomes possible?

That is correct, until this PR we didn't have a need for them.

I'm not quite sure what we want to do about files being added from a terminal or more generally added in WebContainer by any mean, but I'm tempted to think that we'll want to design a solution that around a specific example.

Currently it's intentional that files are modifiable. This is simply to reduce repetition - you don't have to copy-paste files in every single lesson just to make them visible.

Then IMO it's the wrong abstraction. I never saw visibleFiles as intended to reduce repetition in _files. If we want that then we should maybe consider allowing .tk-config.json in _files (which I think already works but isn't documented) or have a different approach. This feels a bit hacky and against the original idea that templates are not part of the lesson (as in initial files to modify or the final solution).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise it feels like we're moving too far away from the original goal of having tutorials be this "safe" environment where learners can focus on the learning.

Yep, it sounds like we need to reconsider these changes. Maybe it's best to have only files from _files visible, as it currently is. Having files that aren't modifiable in file tree could make tutorials even more confusing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this option shouldn't even be on template, it should be just file system based one. 🤔

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh that's a good point actually! It's not really a template property but more like what we should show from the fs regardless of where it's coming from.

Hmm I agree maybe this is something we should discuss further, maybe we could start a thread on twitter about it and ping people that have requested the feature? Or maybe we can have the conversation in a GitHub issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something like:

editor: 
  fileTree: 
     include: ["..."]
     templateFiles: ["..."]

Expand Down Expand Up @@ -374,6 +374,14 @@ export class TutorialStore {
}
}

function filterEntries<T extends object>(obj: T, filter: string[]) {
return Object.fromEntries(Object.entries(obj).filter(([entry]) => filter.includes(entry)));
function pick<T>(obj: Record<string, T>, entries: string[]) {
const result: Record<string, T> = {};

for (const entry of entries) {
if (entry in obj) {
result[entry] = obj[entry];
}
}

return result;
}
5 changes: 3 additions & 2 deletions packages/types/src/schemas/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,16 +177,17 @@ export const webcontainerSchema = commandsSchema.extend({
template: z
.union([
// name of the template
z.string().optional(),
z.string(),

z.strictObject({
// name of the template
name: z.string(),

// list of globs of files that should be visible
visibleFiles: z.array(z.string()).optional(),
visibleFiles: z.array(z.string()).optional().describe('Specifies which files from template should be visible'),
}),
])
.optional()
.describe(
'Specifies which folder from the `src/templates/` directory should be used as the basis for the code. See the "Code templates" guide for a detailed explainer.',
),
Expand Down