Skip to content

Commit 323344b

Browse files
committed
Merge branch 'main' into arpan/cc-1895-add-og-images-for-campus-pages
2 parents 7c6684d + 3b6b789 commit 323344b

28 files changed

+2772
-4305
lines changed

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ module.exports = {
4545
},
4646
],
4747

48-
'ember/no-array-prototype-extensions': 'off', // Get to this later
48+
'ember/no-array-prototype-extensions': 'off', // FIXME: Change to error - prototype extensions are deprecated since Ember 5.10
4949
'ember/no-empty-glimmer-component-classes': 'off', // It's useful to have empty components since the names are shown in devtools
5050
'ember/no-runloop': 'off', // Run-loop isn't deprecated yet. Switching to ember-concurrency would require a lot of effort. We can use ember-lifeline as a drop-in replacement whenever run-loop becomes deprecated.
5151
'@typescript-eslint/member-ordering': [

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ or against a local instance of `core`. Visit the `core` repo for setup instructi
4444
- Add `FASTBOOT_DISABLED=true` to your local `.env` file to disable FastBoot completely
4545
- You can override it by passing `FASTBOOT_DISABLED=""` in the command line
4646
- NPM task `start` runs with FastBoot **disabled**
47-
- NPM tasks `start:fastboot` runs with FastBoot **enabled**
47+
- NPM task `start:fastboot` runs with FastBoot **enabled**
4848

4949
## Running tests
5050

app/app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Application from '@ember/application';
22
import Resolver from 'ember-resolver';
33
import loadInitializers from 'ember-load-initializers';
44
import config from 'codecrafters-frontend/config/environment';
5+
import 'codecrafters-frontend/config/deprecation-workflow';
56
import * as Sentry from '@sentry/ember';
67
import 'ember-basic-dropdown/styles';
78
import 'ember-animated/index';

app/components/course-page/course-stage-step/community-solution-card/changed-file-card.hbs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,11 @@
77
class="bg-gray-100 dark:bg-gray-800 rounded-t py-2 px-4 border-b border-gray-200 dark:border-white/5 shadow-xs flex items-center justify-between sticky top-10 z-10"
88
>
99
<span class="font-mono text-xs text-gray-600 dark:text-gray-300 bold">{{@changedFile.filename}}</span>
10-
<div>
11-
{{#if @solution.isPublishedToPublicGithubRepository}}
12-
<a
13-
{{! @glint-expect-error call not ts-ified yet }}
14-
href={{call (fn @solution.githubUrlForFile @changedFile.filename)}}
15-
target="_blank"
16-
rel="noopener noreferrer"
17-
class="flex gap-x-1 items-center group"
18-
>
19-
<span class="text-[10px] text-gray-700 dark:text-gray-300 group-hover:underline">
20-
View on GitHub
21-
</span>
22-
{{svg-jar "github" class="w-3.5 h-3.5 text-gray-600 dark:text-gray-400"}}
23-
</a>
24-
{{else if this.shouldShowPublishToGithubButton}}
25-
<button type="button" {{on "click" @onPublishToGithubButtonClick}} class="flex gap-x-1 items-center group" data-test-publish-to-github-button>
26-
<span class="text-[10px] text-gray-700 dark:text-gray-300 group-hover:underline">
27-
Publish to GitHub
28-
</span>
29-
{{svg-jar "github" class="w-3.5 h-3.5 text-gray-600 dark:text-gray-400"}}
30-
</button>
31-
{{/if}}
32-
</div>
10+
<CoursePage::CourseStageStep::CommunitySolutionCard::GithubFileActions
11+
@filename={{@changedFile.filename}}
12+
@onPublishToGithubButtonClick={{@onPublishToGithubButtonClick}}
13+
@solution={{@solution}}
14+
/>
3315
</div>
3416

3517
<SyntaxHighlightedDiff

app/components/course-page/course-stage-step/community-solution-card/changed-file-card.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import Component from '@glimmer/component';
2-
import { inject as service } from '@ember/service';
3-
import type AuthenticatorService from 'codecrafters-frontend/services/authenticator';
42
import type CommunityCourseStageSolution from 'codecrafters-frontend/models/community-course-stage-solution';
53

64
interface Signature {
@@ -13,13 +11,7 @@ interface Signature {
1311
};
1412
}
1513

16-
export default class ChangedFileCard extends Component<Signature> {
17-
@service declare authenticator: AuthenticatorService;
18-
19-
get shouldShowPublishToGithubButton(): boolean {
20-
return this.args.solution.user.id === this.authenticator.currentUser?.id && !this.args.solution.isPublishedToPublicGithubRepository;
21-
}
22-
}
14+
export default class ChangedFileCard extends Component<Signature> {}
2315

2416
declare module '@glint/environment-ember-loose/registry' {
2517
export default interface Registry {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<div>
2+
{{#if @solution.isPublishedToPublicGithubRepository}}
3+
<a
4+
{{! @glint-expect-error call not ts-ified yet }}
5+
href={{call (fn @solution.githubUrlForFile @filename)}}
6+
target="_blank"
7+
rel="noopener noreferrer"
8+
class="flex gap-x-1 items-center group"
9+
>
10+
<span class="text-[10px] text-gray-700 dark:text-gray-300 group-hover:underline">
11+
View on GitHub
12+
</span>
13+
{{svg-jar "github" class="w-3.5 h-3.5 text-gray-600 dark:text-gray-400"}}
14+
</a>
15+
{{else if this.shouldShowPublishToGithubButton}}
16+
<button type="button" {{on "click" @onPublishToGithubButtonClick}} class="flex gap-x-1 items-center group" data-test-publish-to-github-button>
17+
<span class="text-[10px] text-gray-700 dark:text-gray-300 group-hover:underline">
18+
Publish to GitHub
19+
</span>
20+
{{svg-jar "github" class="w-3.5 h-3.5 text-gray-600 dark:text-gray-400"}}
21+
</button>
22+
{{else}}
23+
<button
24+
type="button"
25+
{{on "click" this.handleViewOnGithubButtonClick}}
26+
class="flex gap-x-1 items-center group {{if this.isCreatingExport 'opacity-50 cursor-not-allowed'}}"
27+
data-test-view-on-github-button
28+
>
29+
<span class="text-[10px] text-gray-700 dark:text-gray-300 group-hover:underline">
30+
{{#if this.isCreatingExport}}
31+
Loading...
32+
{{else}}
33+
View on GitHub
34+
{{/if}}
35+
</span>
36+
{{svg-jar "github" class="w-3.5 h-3.5 text-gray-600 dark:text-gray-400"}}
37+
</button>
38+
{{/if}}
39+
</div>
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import Component from '@glimmer/component';
2+
import { action } from '@ember/object';
3+
import { inject as service } from '@ember/service';
4+
import { tracked } from '@glimmer/tracking';
5+
import * as Sentry from '@sentry/ember';
6+
import window from 'ember-window-mock';
7+
import type AuthenticatorService from 'codecrafters-frontend/services/authenticator';
8+
import type CommunityCourseStageSolution from 'codecrafters-frontend/models/community-course-stage-solution';
9+
import type CommunitySolutionExportModel from 'codecrafters-frontend/models/community-solution-export';
10+
import type Store from '@ember-data/store';
11+
12+
interface Signature {
13+
Element: HTMLDivElement;
14+
15+
Args: {
16+
filename: string;
17+
onPublishToGithubButtonClick: () => void;
18+
solution: CommunityCourseStageSolution;
19+
};
20+
}
21+
22+
export default class GithubFileActionsComponent extends Component<Signature> {
23+
@service declare authenticator: AuthenticatorService;
24+
@service declare store: Store;
25+
26+
@tracked isCreatingExport = false;
27+
28+
get shouldShowPublishToGithubButton(): boolean {
29+
return this.args.solution.user.id === this.authenticator.currentUser?.id && !this.args.solution.isPublishedToPublicGithubRepository;
30+
}
31+
32+
private async createExport(): Promise<CommunitySolutionExportModel | null> {
33+
if (this.isCreatingExport) return null;
34+
35+
this.isCreatingExport = true;
36+
37+
try {
38+
const exportRecord = await this.args.solution.createExport();
39+
this.isCreatingExport = false;
40+
41+
return exportRecord;
42+
} catch (error) {
43+
Sentry.captureException(error);
44+
this.isCreatingExport = false;
45+
46+
return null;
47+
}
48+
}
49+
50+
private getLatestProvisionedExport(): CommunitySolutionExportModel | null {
51+
return this.args.solution.exports.rejectBy('isExpired').filterBy('isProvisioned').sortBy('expiresAt').lastObject || null;
52+
}
53+
54+
@action
55+
async handleViewOnGithubButtonClick() {
56+
const latestExport = this.getLatestProvisionedExport();
57+
58+
if (latestExport) {
59+
const githubUrl = latestExport.githubUrlForFile(this.args.filename);
60+
latestExport.markAsAccessed({});
61+
window.open(githubUrl, '_blank', 'noopener,noreferrer');
62+
} else {
63+
const exportRecord = await this.createExport();
64+
65+
if (exportRecord) {
66+
const githubUrl = exportRecord.githubUrlForFile(this.args.filename);
67+
window.open(githubUrl, '_blank', 'noopener,noreferrer');
68+
}
69+
}
70+
}
71+
}
72+
73+
declare module '@glint/environment-ember-loose/registry' {
74+
export default interface Registry {
75+
'CoursePage::CourseStageStep::CommunitySolutionCard::GithubFileActions': typeof GithubFileActionsComponent;
76+
}
77+
}

app/components/course-page/course-stage-step/community-solution-card/highlighted-file-card.hbs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,11 @@
77
class="bg-gray-100 dark:bg-gray-800 rounded-t py-2 px-4 border-b border-gray-200 dark:border-white/5 shadow-xs flex items-center justify-between sticky top-10 z-10"
88
>
99
<span class="font-mono text-xs text-gray-600 dark:text-gray-300 bold">{{@highlightedFile.filename}}</span>
10-
<div>
11-
{{#if @solution.isPublishedToPublicGithubRepository}}
12-
<a
13-
{{! @glint-expect-error call not ts-ified yet }}
14-
href={{call (fn @solution.githubUrlForFile @highlightedFile.filename)}}
15-
target="_blank"
16-
rel="noopener noreferrer"
17-
class="flex gap-x-1 items-center group"
18-
>
19-
<span class="text-[10px] text-gray-700 dark:text-gray-300 group-hover:underline">
20-
View on GitHub
21-
</span>
22-
{{svg-jar "github" class="w-3.5 h-3.5 text-gray-600 dark:text-gray-400"}}
23-
</a>
24-
{{else if this.shouldShowPublishToGithubButton}}
25-
<button type="button" {{on "click" @onPublishToGithubButtonClick}} class="flex gap-x-1 items-center group" data-test-publish-to-github-button>
26-
<span class="text-[10px] text-gray-700 dark:text-gray-300 group-hover:underline">
27-
Publish to GitHub
28-
</span>
29-
{{svg-jar "github" class="w-3.5 h-3.5 text-gray-600 dark:text-gray-400"}}
30-
</button>
31-
{{/if}}
32-
</div>
10+
<CoursePage::CourseStageStep::CommunitySolutionCard::GithubFileActions
11+
@filename={{@highlightedFile.filename}}
12+
@onPublishToGithubButtonClick={{@onPublishToGithubButtonClick}}
13+
@solution={{@solution}}
14+
/>
3315
</div>
3416

3517
<CodeMirror

app/components/course-page/course-stage-step/community-solution-card/highlighted-file-card.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import Component from '@glimmer/component';
22
import { inject as service } from '@ember/service';
3-
import type AuthenticatorService from 'codecrafters-frontend/services/authenticator';
43
import type CommunityCourseStageSolution from 'codecrafters-frontend/models/community-course-stage-solution';
54
import type DarkModeService from 'codecrafters-frontend/services/dark-mode';
65
import { codeCraftersDark, codeCraftersLight } from 'codecrafters-frontend/utils/code-mirror-themes';
@@ -17,7 +16,6 @@ interface Signature {
1716
}
1817

1918
export default class HighlightedFileCard extends Component<Signature> {
20-
@service declare authenticator: AuthenticatorService;
2119
@service declare darkMode: DarkModeService;
2220

2321
get codeMirrorTheme() {
@@ -68,10 +66,6 @@ export default class HighlightedFileCard extends Component<Signature> {
6866
}));
6967
}
7068

71-
get shouldShowPublishToGithubButton(): boolean {
72-
return this.args.solution.user.id === this.authenticator.currentUser?.id && !this.args.solution.isPublishedToPublicGithubRepository;
73-
}
74-
7569
get visibleRangesForCodeMirror(): LineRange[] {
7670
// Add 3 lines above and below the highlighted range
7771
const ranges = this.args.highlightedFile.highlighted_ranges.map((range) => ({

app/config/deprecation-workflow.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import setupDeprecationWorkflow from 'ember-cli-deprecation-workflow';
2+
3+
setupDeprecationWorkflow({
4+
throwOnUnhandled: true,
5+
workflow: [],
6+
});

0 commit comments

Comments
 (0)