From 910dcfba8fa7ff8115eb0f4ae9d5fddef5145856 Mon Sep 17 00:00:00 2001 From: NazarMykhalkevych Date: Thu, 19 Jun 2025 15:49:05 +0300 Subject: [PATCH 1/2] feat(wiki): add autocomplete, refactoring --- angular.json | 3 +- package.json | 5 +- src/@types/markdown-it-video.d.ts | 9 ++ src/app/app.config.ts | 2 + .../overview-wiki.component.html | 4 +- .../overview-wiki/overview-wiki.component.ts | 3 +- .../compare-section.component.ts | 18 +--- .../edit-section/edit-section.component.html | 19 ++-- .../edit-section/edit-section.component.ts | 47 ++++++++-- .../view-section/view-section.component.html | 2 +- .../view-section/view-section.component.ts | 5 +- .../project/wiki/services/wiki.service.ts | 3 +- .../features/project/wiki/wiki.component.html | 1 + .../features/project/wiki/wiki.component.ts | 1 - .../markdown/markdown.component.html | 1 + .../markdown/markdown.component.scss | 0 .../markdown/markdown.component.spec.ts | 22 +++++ .../components/markdown/markdown.component.ts | 36 ++++++++ .../truncated-text.component.html | 20 +++-- .../truncated-text.component.ts | 1 + src/assets/js/ace/snippetsMarkdown.js | 86 +++++++++++++++++++ src/assets/styles/components/md-editor.scss | 18 ++++ tsconfig.app.json | 16 +++- 23 files changed, 271 insertions(+), 51 deletions(-) create mode 100644 src/@types/markdown-it-video.d.ts create mode 100644 src/app/shared/components/markdown/markdown.component.html create mode 100644 src/app/shared/components/markdown/markdown.component.scss create mode 100644 src/app/shared/components/markdown/markdown.component.spec.ts create mode 100644 src/app/shared/components/markdown/markdown.component.ts create mode 100644 src/assets/js/ace/snippetsMarkdown.js diff --git a/angular.json b/angular.json index 8f6c4ae33..177c344fd 100644 --- a/angular.json +++ b/angular.json @@ -49,7 +49,8 @@ }, "scripts": [ "node_modules/ngx-markdown-editor/assets/highlight.js/highlight.min.js", - "node_modules/ngx-markdown-editor/assets/marked.min.js" + "node_modules/ngx-markdown-editor/assets/marked.min.js", + "src/assets/js/ace/snippetsMarkdown.js" ] }, "configurations": { diff --git a/package.json b/package.json index 775f3508d..ee4605f0b 100644 --- a/package.json +++ b/package.json @@ -43,13 +43,14 @@ "ace-builds": "^1.42.0", "chart.js": "^4.4.9", "diff": "^8.0.2", + "markdown-it": "^14.1.0", + "markdown-it-video": "^0.6.3", "ngx-markdown-editor": "^5.3.4", "primeflex": "^4.0.0", "primeicons": "^7.0.0", "primeng": "^19.0.9", "rxjs": "~7.8.0", "tslib": "^2.3.0", - "turndown": "^7.2.0", "zone.js": "~0.15.0" }, "devDependencies": { @@ -60,7 +61,7 @@ "@commitlint/config-conventional": "^19.7.1", "@types/jasmine": "~5.1.0", "@types/jest": "^29.5.14", - "@types/turndown": "^5.0.5", + "@types/markdown-it": "^14.1.2", "angular-eslint": "19.1.0", "angularx-qrcode": "^19.0.0", "eslint": "^9.20.0", diff --git a/src/@types/markdown-it-video.d.ts b/src/@types/markdown-it-video.d.ts new file mode 100644 index 000000000..1006af646 --- /dev/null +++ b/src/@types/markdown-it-video.d.ts @@ -0,0 +1,9 @@ +declare module 'markdown-it-video' { + import { PluginSimple } from 'markdown-it'; + + const videoPlugin: PluginSimple; + export default videoPlugin; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +declare const ace: any; diff --git a/src/app/app.config.ts b/src/app/app.config.ts index ab079babd..bdb631834 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -1,6 +1,7 @@ import { withNgxsReduxDevtoolsPlugin } from '@ngxs/devtools-plugin'; import { provideStore } from '@ngxs/store'; +import { provideMarkdown } from 'ngx-markdown'; import { TranslateModule } from '@ngx-translate/core'; import { ConfirmationService, MessageService } from 'primeng/api'; @@ -42,5 +43,6 @@ export const appConfig: ApplicationConfig = { ConfirmationService, MessageService, { provide: ErrorHandler, useClass: GlobalErrorHandler }, + provideMarkdown(), ], }; diff --git a/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.html b/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.html index f0f538741..84fc750cf 100644 --- a/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.html +++ b/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.html @@ -4,7 +4,9 @@

{{ 'project.overview.wiki.title' | translate }}

} @else { @if (wikiContent()) { - + + + } @else {
} diff --git a/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.ts b/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.ts index 7c99fe996..13f64c43c 100644 --- a/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.ts +++ b/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.ts @@ -7,11 +7,12 @@ import { Skeleton } from 'primeng/skeleton'; import { ChangeDetectionStrategy, Component } from '@angular/core'; import { WikiSelectors } from '@osf/features/project/wiki/store'; +import { MarkdownComponent } from '@osf/shared/components/markdown/markdown.component'; import { TruncatedTextComponent } from '@shared/components'; @Component({ selector: 'osf-project-wiki', - imports: [Skeleton, TranslatePipe, TruncatedTextComponent], + imports: [Skeleton, TranslatePipe, TruncatedTextComponent, MarkdownComponent], templateUrl: './overview-wiki.component.html', styleUrl: './overview-wiki.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/features/project/wiki/components/compare-section/compare-section.component.ts b/src/app/features/project/wiki/components/compare-section/compare-section.component.ts index b11bc130d..901b1130f 100644 --- a/src/app/features/project/wiki/components/compare-section/compare-section.component.ts +++ b/src/app/features/project/wiki/components/compare-section/compare-section.component.ts @@ -10,7 +10,6 @@ import { FormsModule } from '@angular/forms'; import { WikiVersion } from '../../models'; import * as Diff from 'diff'; -import TurndownService from 'turndown'; @Component({ selector: 'osf-compare-section', @@ -39,10 +38,7 @@ export class CompareSectionComponent { ]); content = computed(() => { - const changes = Diff.diffWords( - this.convertHtmlToMarkdown(this.versionContent()), - this.convertHtmlToMarkdown(this.previewContent()) - ); + const changes = Diff.diffWords(this.versionContent(), this.previewContent()); return changes .map((change) => { if (change.added) { @@ -61,18 +57,6 @@ export class CompareSectionComponent { this.selectVersion.emit(this.selectedVersion); }); } - convertHtmlToMarkdown(html: string): string { - const turndownService = new TurndownService({ - headingStyle: 'atx', - emDelimiter: '*', - strongDelimiter: '**', - hr: '---', - linkStyle: 'inlined', - bulletListMarker: '-', - codeBlockStyle: 'indented', - }); - return turndownService.turndown(html); - } onVersionChange(versionId: string): void { this.selectedVersion = versionId; this.selectVersion.emit(versionId); diff --git a/src/app/features/project/wiki/components/edit-section/edit-section.component.html b/src/app/features/project/wiki/components/edit-section/edit-section.component.html index 5c7eda186..838eaf3e1 100644 --- a/src/app/features/project/wiki/components/edit-section/edit-section.component.html +++ b/src/app/features/project/wiki/components/edit-section/edit-section.component.html @@ -22,7 +22,7 @@

{{ 'project.wiki.edit' | translate }}

[(ngModel)]="content" [options]="options" (onEditorLoaded)="onEditorLoaded($event)" - (onPreviewDomChanged)="onPreviewDomChanged($event)" + (onPreviewDomChanged)="onPreviewDomChanged()" height="100%" > @@ -32,10 +32,19 @@

{{ 'project.wiki.edit' | translate }}

-
- + +
+ +