Skip to content

Commit de7353a

Browse files
authored
[showcase] Add support to navigate between different versions in the showcase (#663)
* Add support to navigate between different versions in the showcase * Update version-selector.scss * Update version-selector.scss * Add warning message for no longer maintained version * Undo change for local testing
1 parent f3012dc commit de7353a

File tree

9 files changed

+189
-13
lines changed

9 files changed

+189
-13
lines changed

packages/showcase/src/app/app.component.html

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
'components/checkbox',
55
'components/code',
66
'components/dialog',
7+
'components/dropdown',
78
'components/edit',
89
'components/icon',
910
'components/navigation-list',
@@ -28,7 +29,8 @@
2829
</p></a
2930
>
3031

31-
<span class="elevation-2 app-header__version">v{{ libraryVersion }}</span>
32+
<version-selector></version-selector>
33+
3234
@let isIconsPage =
3335
selectedLink().id !== "/" &&
3436
commonLinks.coreConcepts_icons().includes(selectedLink().id!);
@@ -106,6 +108,23 @@
106108

107109
<main>
108110
<article>
111+
@if (selectedLink().id !== "/" && !versioning.isLatestVersion()) {
112+
<blockquote class="blockquote-warning version-no-longer-maintained">
113+
<p>
114+
This is documentation for Mercury
115+
<span class="body-semi-bold-m">{{ libraryVersion }}</span
116+
>, which is no longer actively maintained.
117+
</p>
118+
119+
<p>
120+
For up-to-date documentation, see the
121+
<a class="body-semi-bold-m" href="/"
122+
>latest Mercury version ({{ versioning.latestVersion() }})</a
123+
>.
124+
</p>
125+
</blockquote>
126+
}
127+
109128
<router-outlet style="display: contents" />
110129
</article>
111130
</main>

packages/showcase/src/app/app.component.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ import {
4242
} from "../services/design-system.service";
4343
import { RouterCommonLinksService } from "../services/router-links.service";
4444
import { SEOService } from "../services/seo.service";
45+
import { VersioningService } from "../services/versioning.service";
4546
import { PageFiltersComponent } from "../user-controls/page-filters/page-filters.ng";
47+
import { VersionSelectorComponent } from "../user-controls/version-selector/version-selector";
4648
import { mercuryVersion } from "./mercury-version";
4749

4850
const MERCURY_UNANIMO_PREFIX_URL_REGEX = /\/(mercury|unanimo)/;
@@ -53,13 +55,20 @@ const FRAGMENT_QUERY_PARAMS_URL = /(#.*|\?.*)/;
5355
templateUrl: "./app.component.html",
5456
styleUrl: "./app.scss",
5557
changeDetection: ChangeDetectionStrategy.OnPush,
56-
imports: [RouterOutlet, RouterLink, PageFiltersComponent, RuntimeBundlesComponent],
58+
imports: [
59+
RouterOutlet,
60+
RouterLink,
61+
PageFiltersComponent,
62+
RuntimeBundlesComponent,
63+
VersionSelectorComponent
64+
],
5765
schemas: [CUSTOM_ELEMENTS_SCHEMA],
5866
host: { ngSkipHydration: "true" }
5967
})
6068
export class AppComponent {
6169
location = inject(Location);
6270
platform = inject(PLATFORM_ID);
71+
versioning = inject(VersioningService);
6372
router = inject(Router);
6473
route = inject(ActivatedRoute);
6574
commonLinks = inject(RouterCommonLinksService);
@@ -90,7 +99,7 @@ export class AppComponent {
9099
}
91100
];
92101

93-
protected libraryVersion = mercuryVersion;
102+
libraryVersion = `v${mercuryVersion}`;
94103

95104
constructor() {
96105
this.router.events.subscribe(event => {

packages/showcase/src/app/app.scss

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,10 @@
4747
}
4848
}
4949

50-
&__version {
51-
padding-inline: 8px;
52-
padding-block: 4px;
53-
border-radius: 16px;
54-
margin-inline-start: 8px;
55-
}
56-
5750
&__filters {
5851
position: fixed;
5952
min-inline-size: 230px;
60-
inset-inline-start: var(--app-sidebar-size);
53+
inset-inline-start: calc(var(--app-sidebar-size) + 64px);
6154
}
6255

6356
&__separator {
@@ -115,3 +108,8 @@ main {
115108
padding-block: 6px;
116109
}
117110
}
111+
112+
.version-no-longer-maintained {
113+
justify-self: center;
114+
margin-block-end: 48px;
115+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const mercuryVersion = "0.33.0";
1+
export const mercuryVersion = "0.34.0";
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { isPlatformBrowser } from "@angular/common";
2+
import { computed, inject, Injectable, PLATFORM_ID, signal } from "@angular/core";
3+
import { mercuryVersion } from "../app/mercury-version";
4+
5+
const getLatestVersion = (availableVersions: string[]) =>
6+
availableVersions.find(
7+
version =>
8+
!version.includes("-") && !version.includes("beta") && !version.includes("next")
9+
);
10+
11+
const checkIfCurrentVersionIsTheLatest = (
12+
latestReleasedVersion: string | undefined
13+
): boolean => {
14+
if (!latestReleasedVersion) {
15+
return false;
16+
}
17+
latestReleasedVersion = latestReleasedVersion.trim().replace(/^v/, "");
18+
19+
return latestReleasedVersion === mercuryVersion;
20+
};
21+
22+
@Injectable({ providedIn: "root" })
23+
export class VersioningService {
24+
platform = inject(PLATFORM_ID);
25+
allVersions = signal<string[]>([]);
26+
27+
latestVersion = computed<string | undefined>(() =>
28+
getLatestVersion(this.allVersions())
29+
);
30+
31+
isLatestVersion = computed<boolean>(() =>
32+
checkIfCurrentVersionIsTheLatest(this.latestVersion())
33+
);
34+
35+
constructor() {
36+
if (isPlatformBrowser(this.platform)) {
37+
// fetch("/services/versions")
38+
fetch("/services/versions")
39+
.then(response => response.json())
40+
.then(versions => this.allVersions.set(versions))
41+
.catch(err =>
42+
console.error("Error getting the versions from the server", err)
43+
);
44+
}
45+
}
46+
}

packages/showcase/src/styles.scss

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ ch-code {
9595
.blockquote-info {
9696
padding: 16px;
9797
margin: 0;
98-
margin-block-start: 16px;
9998
border-inline-start: 2px solid var(--color-border-neutral-default);
10099
background-color: var(--mer-surface__elevation--01);
101100
border-radius: 4px;
@@ -106,6 +105,17 @@ ch-code {
106105
background-color: var(--mer-color__neutral-gray--600);
107106
}
108107

108+
.blockquote-warning {
109+
padding: 16px;
110+
margin: 0;
111+
margin-block-start: 16px;
112+
border-inline-start: 2px solid var(--color-border-neutral-default);
113+
background-color: var(--mer-color__message-yellow--200);
114+
border-radius: 4px;
115+
color: var(--mer-text__on-message);
116+
line-height: 1.5;
117+
}
118+
109119
.hyperlink {
110120
color: var(--mer-accent__primary, var(--text__primary));
111121
text-decoration: underline;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<ch-action-menu-render
2+
class="version-selector dropdown"
3+
[model]="allVersions()"
4+
[inlineAlign]="'inside-start'"
5+
>{{version}}
6+
<ch-image class="version-selector-chevron" [src]="chevronDown" type="mask" />
7+
</ch-action-menu-render>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
ch-action-menu-render.version-selector {
2+
&::part(expandable-button) {
3+
background-color: var(--mer-surface__elevation--02);
4+
padding-inline: 8px 6px;
5+
padding-block: 4px;
6+
border-radius: 4px;
7+
margin-inline-start: 12px;
8+
9+
&:hover {
10+
background-color: var(--mer-surface__elevation--03);
11+
}
12+
}
13+
14+
&::part(window) {
15+
--ch-popover-separation-y: 4px;
16+
}
17+
18+
&::part(action link) {
19+
text-decoration: unset;
20+
}
21+
22+
// TODO: At the moment, we cannot style the button inside the action part
23+
// with custom parts due to a bug in Chameleon. Once fixed, we can remove
24+
// this workaround.
25+
&::part(action button) {
26+
background-color: var(--item__bg-color--selected);
27+
border-color: var(--item__border-color--selected);
28+
color: var(--mer-accent__primary);
29+
}
30+
}
31+
32+
.version-selector-chevron {
33+
--ch-image-size: 16px;
34+
margin-inline-start: 6px;
35+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import {
2+
ChangeDetectionStrategy,
3+
Component,
4+
computed,
5+
CUSTOM_ELEMENTS_SCHEMA,
6+
inject,
7+
ViewEncapsulation
8+
} from "@angular/core";
9+
import type { ActionMenuModel } from "@genexus/chameleon-controls-library";
10+
import type { ActionMenuItemModel } from "@genexus/chameleon-controls-library/dist/types/components/action-menu/types";
11+
import { getIconPath } from "@genexus/mercury/assets-manager.js";
12+
import { mercuryVersion } from "../../app/mercury-version";
13+
import { VersioningService } from "../../services/versioning.service";
14+
15+
const getVersionUrl = (version: string, latestVersion: string | undefined) =>
16+
latestVersion === version ? "/" : `/${version}`;
17+
18+
@Component({
19+
selector: "version-selector",
20+
templateUrl: "./version-selector.ng.html",
21+
styleUrl: "./version-selector.scss",
22+
changeDetection: ChangeDetectionStrategy.OnPush,
23+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
24+
encapsulation: ViewEncapsulation.None
25+
})
26+
export class VersionSelectorComponent {
27+
versioningService = inject(VersioningService);
28+
29+
allVersions = computed<ActionMenuModel>(() =>
30+
this.versioningService.allVersions().map(
31+
version =>
32+
({
33+
caption: version.replace("-beta", " (Beta)"),
34+
id: version,
35+
link:
36+
version === this.version
37+
? undefined
38+
: {
39+
url: getVersionUrl(version, this.versioningService.latestVersion())
40+
}
41+
}) satisfies ActionMenuItemModel
42+
)
43+
);
44+
45+
protected version = `v${mercuryVersion}`;
46+
47+
protected chevronDown = getIconPath({
48+
category: "navigation",
49+
name: "chevron-down",
50+
colorType: "on-elevation"
51+
});
52+
}

0 commit comments

Comments
 (0)