Skip to content

Commit e2d9f8b

Browse files
committed
feat(client): parse cluster nodes into the result structure, implement cluster ui
1 parent 1dc7685 commit e2d9f8b

9 files changed

+153
-79
lines changed

libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.html

+21-3
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,35 @@
1818
>
1919
@for (layer of roadmapLayers(); track layer.parentNode.id) {
2020
<div class="flex w-full flex-col items-center gap-12">
21-
<al-ui-roadmap-node [node]="layer.parentNode" />
21+
@if (layer.parentNode.nodeType === 'primary') {
22+
<al-ui-roadmap-primary-node [node]="layer.parentNode" />
23+
} @else if (layer.parentNode.nodeType === 'angular-love') {
24+
<al-ui-roadmap-angular-love-node
25+
[node]="layer.parentNode"
26+
></al-ui-roadmap-angular-love-node>
27+
}
2228
@if (layer.childNodes?.length) {
2329
<div class="flex gap-12">
2430
@for (node of layer.childNodes | leftSlice; track node.id) {
2531
<div class="flex gap-10">
26-
<al-ui-roadmap-node [node]="node" />
32+
@if (node.nodeType === 'secondary') {
33+
<al-ui-roadmap-secondary-node [node]="node" />
34+
} @else if (node.nodeType === 'cluster') {
35+
<al-ui-roadmap-cluster
36+
[cluster]="$any(node)"
37+
></al-ui-roadmap-cluster>
38+
}
2739
</div>
2840
}
2941
@for (node of layer.childNodes | rightSlice; track node.id) {
3042
<div class="flex gap-10">
31-
<al-ui-roadmap-node [node]="node" />
43+
@if (node.nodeType === 'secondary') {
44+
<al-ui-roadmap-secondary-node [node]="node" />
45+
} @else if (node.nodeType === 'cluster') {
46+
<al-ui-roadmap-cluster
47+
[cluster]="$any(node)"
48+
></al-ui-roadmap-cluster>
49+
}
3250
</div>
3351
}
3452
</div>

libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.ts

+17-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import {
66
} from '@angular/core';
77

88
import { LeftSlicePipe, RightSlicePipe } from './slice.pipes';
9-
import { UiRoadmapNodeComponent } from './ui-roadmap-node.component';
9+
import { UiRoadmapAngularLoveNodeComponent } from './ui/ui-roadmap-angular-love-node.component';
10+
import { UiRoadmapClusterComponent } from './ui/ui-roadmap-cluster.component';
11+
import { UiRoadmapPrimaryNodeComponent } from './ui/ui-roadmap-primary-node.component';
12+
import { UiRoadmapSecondaryNodeComponent } from './ui/ui-roadmap-secondary-node.component';
1013

1114
export type NodeType = 'primary' | 'secondary' | 'cluster' | 'angular-love';
1215

@@ -35,7 +38,14 @@ export interface RoadmapLayer {
3538

3639
@Component({
3740
selector: 'al-feature-roadmap',
38-
imports: [UiRoadmapNodeComponent, LeftSlicePipe, RightSlicePipe],
41+
imports: [
42+
LeftSlicePipe,
43+
RightSlicePipe,
44+
UiRoadmapClusterComponent,
45+
UiRoadmapPrimaryNodeComponent,
46+
UiRoadmapAngularLoveNodeComponent,
47+
UiRoadmapSecondaryNodeComponent,
48+
],
3949
templateUrl: './feature-roadmap.component.html',
4050
styleUrl: './feature-roadmap.component.scss',
4151
changeDetection: ChangeDetectionStrategy.OnPush,
@@ -73,6 +83,11 @@ export class FeatureRoadmapComponent {
7383
parentNodeId: '4',
7484
title: 'Sass',
7585
},
86+
{
87+
id: '8',
88+
previousNodeId: '2',
89+
title: 'Modules',
90+
},
7691
]);
7792

7893
protected readonly roadmapLayers = computed<RoadmapLayer[]>(() => {

libs/blog/roadmap/feature-roadmap/src/lib/ui-roadmap-cluster.component.ts

-26
This file was deleted.

libs/blog/roadmap/feature-roadmap/src/lib/ui-roadmap-node.component.ts

-42
This file was deleted.

libs/blog/roadmap/feature-roadmap/src/lib/ui-roadmap-node.component.scss renamed to libs/blog/roadmap/feature-roadmap/src/lib/ui/roadmap-hover-border-gradient.scss

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
.node-container {
1+
.roadmap-hover-border-gradient {
22
position: relative;
33
overflow: hidden;
44

55
&::before {
66
content: '';
77
display: block;
88
position: absolute;
9-
width: 1000%;
10-
height: 1000%;
11-
top: -450%;
12-
left: -450%;
9+
width: 2000px;
10+
height: 2000px;
11+
top: calc(50% - 1000px);
12+
left: calc(50% - 1000px);
1313
background: conic-gradient(#ff006a, #923cff, #ff006a);
1414
opacity: 0;
1515
transition: opacity 0.2s ease-in-out;
1616
z-index: 1;
1717
}
1818

19-
&:hover::before {
19+
&:not(.cluster-node):hover::before {
2020
opacity: 1;
2121
animation: rotate 1s linear infinite;
2222
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Component, input } from '@angular/core';
2+
3+
import { RoadmapNode } from '../feature-roadmap.component';
4+
5+
@Component({
6+
selector: 'al-ui-roadmap-angular-love-node',
7+
template: `
8+
<div
9+
class="roadmap-hover-border-gradient relative w-fit text-nowrap rounded-lg bg-[#FDF5FD] text-[#FDF5FD]"
10+
style="
11+
--primary-color: #B3004A; --secondary-color: #66002B; --gradient-color: #481CAB; --on-hover-border-1: #923CFF; --on-hover-border-2: #FF006A"
12+
>
13+
<div
14+
class="relative z-10 m-[4px] rounded-lg bg-gradient-to-r from-[--secondary-color] to-[--gradient-color] px-6 py-4"
15+
>
16+
<div class="text-[24px]">{{ node().title }}</div>
17+
</div>
18+
</div>
19+
`,
20+
styleUrls: ['./roadmap-hover-border-gradient.scss'],
21+
})
22+
export class UiRoadmapAngularLoveNodeComponent {
23+
readonly node = input.required<RoadmapNode>();
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Component, input } from '@angular/core';
2+
3+
import { RoadmapCluster } from '../feature-roadmap.component';
4+
5+
@Component({
6+
selector: 'al-ui-roadmap-cluster',
7+
template: `
8+
<div
9+
class="relative z-10 m-[-2px] rounded-lg border-2 border-[#FDF5FD] bg-[--secondary-color] px-6 py-4"
10+
>
11+
<div class="text-[20px]">{{ cluster().title }}</div>
12+
</div>
13+
<div class="m-[2px] flex flex-col gap-[10px] p-3">
14+
@for (clusterNode of cluster().clusteredNodes; track clusterNode.id) {
15+
<div
16+
class="roadmap-hover-border-gradient relative w-full text-nowrap rounded-lg bg-[#FDF5FD] text-[#FDF5FD]"
17+
>
18+
<div
19+
class="relative z-10 m-[1px] rounded-lg bg-[--secondary-color] px-6 py-4"
20+
>
21+
<div class="text-[20px]">{{ clusterNode.title }}</div>
22+
</div>
23+
</div>
24+
}
25+
</div>
26+
`,
27+
host: {
28+
class:
29+
'block bg-gradient-to-br from-[#100F15] to-[#3B0019] rounded-lg text-center border-2 border-[#FDF5FD]',
30+
style:
31+
'--primary-color: #B3004A; --secondary-color: #66002B; --gradient-color: #481CAB; --on-hover-border-1: #923CFF; --on-hover-border-2: #FF006A',
32+
},
33+
styleUrls: ['./roadmap-hover-border-gradient.scss'],
34+
})
35+
export class UiRoadmapClusterComponent {
36+
readonly cluster = input.required<RoadmapCluster>();
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Component, input } from '@angular/core';
2+
3+
import { RoadmapNode } from '../feature-roadmap.component';
4+
5+
@Component({
6+
selector: 'al-ui-roadmap-primary-node',
7+
template: `
8+
<div
9+
class="roadmap-hover-border-gradient relative w-fit text-nowrap rounded-lg bg-[#FDF5FD] text-[#FDF5FD]"
10+
style="
11+
--primary-color: #B3004A; --secondary-color: #66002B; --gradient-color: #481CAB; --on-hover-border-1: #923CFF; --on-hover-border-2: #FF006A"
12+
>
13+
<div
14+
class="relative z-10 m-[4px] rounded-lg bg-[--primary-color] px-6 py-4"
15+
>
16+
<div class="text-[24px]">{{ node().title }}</div>
17+
</div>
18+
</div>
19+
`,
20+
styleUrls: ['./roadmap-hover-border-gradient.scss'],
21+
})
22+
export class UiRoadmapPrimaryNodeComponent {
23+
readonly node = input.required<RoadmapNode>();
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Component, input } from '@angular/core';
2+
3+
import { RoadmapNode } from '../feature-roadmap.component';
4+
5+
@Component({
6+
selector: 'al-ui-roadmap-secondary-node',
7+
template: `
8+
<div
9+
class="roadmap-hover-border-gradient relative w-fit text-nowrap rounded-lg bg-[#FDF5FD] text-[#FDF5FD]"
10+
style="
11+
--primary-color: #B3004A; --secondary-color: #66002B; --gradient-color: #481CAB; --on-hover-border-1: #923CFF; --on-hover-border-2: #FF006A"
12+
>
13+
<div
14+
class="relative z-10 m-[2px] rounded-lg bg-[--secondary-color] px-6 py-4"
15+
>
16+
<div class="text-[20px]">{{ node().title }}</div>
17+
</div>
18+
</div>
19+
`,
20+
styleUrls: ['./roadmap-hover-border-gradient.scss'],
21+
})
22+
export class UiRoadmapSecondaryNodeComponent {
23+
readonly node = input.required<RoadmapNode>();
24+
}

0 commit comments

Comments
 (0)