Skip to content

Commit 21e8438

Browse files
Merge pull request #120 from CenterForOpenScience/feat/222-wiki-page-compare
feat(wiki): compare view
2 parents a439b60 + 0432296 commit 21e8438

File tree

6 files changed

+55
-9
lines changed

6 files changed

+55
-9
lines changed

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@
4242
"@primeng/themes": "^19.0.9",
4343
"ace-builds": "^1.42.0",
4444
"chart.js": "^4.4.9",
45+
"diff": "^8.0.2",
4546
"ngx-markdown-editor": "^5.3.4",
4647
"primeflex": "^4.0.0",
4748
"primeicons": "^7.0.0",
4849
"primeng": "^19.0.9",
4950
"rxjs": "~7.8.0",
5051
"tslib": "^2.3.0",
52+
"turndown": "^7.2.0",
5153
"zone.js": "~0.15.0"
5254
},
5355
"devDependencies": {
@@ -58,6 +60,7 @@
5860
"@commitlint/config-conventional": "^19.7.1",
5961
"@types/jasmine": "~5.1.0",
6062
"@types/jest": "^29.5.14",
63+
"@types/turndown": "^5.0.5",
6164
"angular-eslint": "19.1.0",
6265
"angularx-qrcode": "^19.0.0",
6366
"eslint": "^9.20.0",

src/app/features/project/wiki/components/compare-section/compare-section.component.html

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ <h2 class="mr-2">{{ 'project.wiki.compare' | translate }}</h2>
1919
styleClass="select-version"
2020
/>
2121
</div>
22-
<p-panel showHeader="false">
23-
<p class="mt-3">
24-
{{ versionContent() }}
25-
</p>
22+
<p-panel styleClass="compare-view" showHeader="false">
23+
<div lass="mt-3" [innerHTML]="content()"></div>
2624
</p-panel>
2725
</p-panel>
2826
}

src/app/features/project/wiki/components/compare-section/compare-section.component.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import { FormsModule } from '@angular/forms';
99

1010
import { WikiVersion } from '../../models';
1111

12+
import * as Diff from 'diff';
13+
import TurndownService from 'turndown';
14+
1215
@Component({
1316
selector: 'osf-compare-section',
1417
imports: [PanelModule, Select, FormsModule, TranslatePipe, Skeleton],
@@ -19,28 +22,57 @@ import { WikiVersion } from '../../models';
1922
export class CompareSectionComponent {
2023
versions = input.required<WikiVersion[]>();
2124
versionContent = input.required<string>();
25+
previewContent = input.required<string>();
2226
isLoading = input.required<boolean>();
2327
selectVersion = output<string>();
2428

2529
selectedVersion: string | null = null;
2630

2731
mappedVersions = computed(() => [
2832
...this.versions().map((version, index) => {
29-
const labelPrefix = index === 0 ? '(Current)' : `(${index})`;
33+
const labelPrefix = index === 0 ? '(Current)' : `(${this.versions().length - index})`;
3034
return {
3135
label: `${labelPrefix} ${version.createdBy}: (${new Date(version.createdAt).toLocaleString()})`,
3236
value: version.id,
3337
};
3438
}),
3539
]);
3640

41+
content = computed(() => {
42+
const changes = Diff.diffWords(
43+
this.convertHtmlToMarkdown(this.versionContent()),
44+
this.convertHtmlToMarkdown(this.previewContent())
45+
);
46+
return changes
47+
.map((change) => {
48+
if (change.added) {
49+
return `<span class="added">${change.value}</span>`;
50+
} else if (change.removed) {
51+
return `<span class="removed">${change.value}</span>`;
52+
}
53+
return change.value;
54+
})
55+
.join('');
56+
});
57+
3758
constructor() {
3859
effect(() => {
39-
this.versions();
40-
this.selectedVersion = null;
60+
this.selectedVersion = this.versions()[0].id;
61+
this.selectVersion.emit(this.selectedVersion);
4162
});
4263
}
43-
64+
convertHtmlToMarkdown(html: string): string {
65+
const turndownService = new TurndownService({
66+
headingStyle: 'atx',
67+
emDelimiter: '*',
68+
strongDelimiter: '**',
69+
hr: '---',
70+
linkStyle: 'inlined',
71+
bulletListMarker: '-',
72+
codeBlockStyle: 'indented',
73+
});
74+
return turndownService.turndown(html);
75+
}
4476
onVersionChange(versionId: string): void {
4577
this.selectedVersion = versionId;
4678
this.selectVersion.emit(versionId);

src/app/features/project/wiki/components/view-section/view-section.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export class ViewSectionComponent {
3838
mappedVersions = computed(() => [
3939
this.previewOption,
4040
...this.versions().map((version, index) => {
41-
const labelPrefix = index === 0 ? '(Current)' : `(${index})`;
41+
const labelPrefix = index === 0 ? '(Current)' : `(${this.versions().length - index})`;
4242
return {
4343
label: `${labelPrefix} ${version.createdBy}: (${new Date(version.createdAt).toLocaleString()})`,
4444
value: version.id,

src/app/features/project/wiki/wiki.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
@if (wikiModes().compare) {
4949
<osf-compare-section
5050
[versions]="wikiVersions()"
51+
[previewContent]="previewContent()"
5152
[versionContent]="compareVersionContent()"
5253
[isLoading]="isWikiVersionLoading()"
5354
(selectVersion)="onSelectCompareVersion($event)"

src/assets/styles/components/md-editor.scss

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,15 @@
8383
display: none;
8484
}
8585
}
86+
87+
.compare-view {
88+
white-space: pre-wrap;
89+
90+
.added {
91+
background-color: var(--green-2);
92+
}
93+
94+
.removed {
95+
background-color: var(--red-2);
96+
}
97+
}

0 commit comments

Comments
 (0)