Skip to content

Feat/angular-roadmap-svg-zoom #429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

DamianBrzezinskiHoA
Copy link
Contributor

@DamianBrzezinskiHoA DamianBrzezinskiHoA commented Apr 7, 2025

DO NOT CHECK
It is a feature that is mainly connected with angular-roadmap feature

Summary by CodeRabbit

  • New Features
    • Launched an interactive roadmap view that visually displays dynamic layers and interconnected nodes with engaging hover effects and smooth animations.
    • Introduced a dedicated section accessible via the main navigation, complete with an integrated header, search functionality, and footer.
    • Enhanced user experience with responsive SVG interactions, including zoom and pan capabilities for a more immersive exploration of the roadmap.

Copy link

coderabbitai bot commented Apr 7, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This pull request introduces a new roadmap feature within the blog library. It adds complete configuration files for ESLint, Jest, and TypeScript along with project metadata. New Angular components, pipes, and style files enable rendering an interactive roadmap using SVG elements. Additionally, the changes update routing in the blog shell to include the roadmap feature and incorporate a new dependency for SVG manipulation.

Changes

Files Change Summary
libs/blog/roadmap/feature-roadmap/.eslintrc.json
libs/blog/roadmap/feature-roadmap/jest.config.ts
libs/blog/roadmap/feature-roadmap/project.json
libs/blog/roadmap/feature-roadmap/README.md
libs/blog/roadmap/feature-roadmap/tsconfig*.json
New configuration and documentation files, including ESLint, Jest, project, and multiple TypeScript configurations for library and test setups.
libs/blog/roadmap/feature-roadmap/src/index.ts Re-export added to expose the public members of the feature roadmap component.
libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.*
(HTML, SCSS, TS, Spec)
New Angular component for the feature roadmap with its template, styles, logic, and tests.
libs/blog/roadmap/feature-roadmap/src/lib/secondary-arrow.pipe.ts
libs/blog/roadmap/feature-roadmap/src/lib/slice.pipes.ts
New Angular pipes for generating SVG arrow shapes and slicing arrays.
libs/blog/roadmap/feature-roadmap/src/lib/ui/roadmap-hover-border-gradient.scss New SCSS file creating hover border gradient effects.
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-angular-love-node.component.ts
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-cluster.component.ts
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-primary-node.component.ts
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-secondary-node.component.ts
New Angular UI components to render various nodes in the roadmap (angular love node, cluster, primary, secondary).
libs/blog/roadmap/feature-roadmap/src/test-setup.ts New test setup file to configure the testing environment for Angular.
libs/blog/shell/feature-shell-web/src/lib/blog-shell.routes.ts
libs/blog/shell/feature-shell-web/src/lib/roadmap-shell.component.ts
libs/blog/shell/feature-shell-web/src/lib/root-shell.component.ts
Updates to the shell: a new route for the roadmap feature, a new roadmap shell component, and an added host styling to the root shell component.
package.json New dependency "svg-pan-zoom": "^3.6.2" added to support SVG manipulation.
tsconfig.base.json Path mapping added for @angular-love/feature-roadmap to reference the feature roadmap’s index file.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant BlogShell
    participant RoadmapShell as Roadmap Shell
    participant FeatureRoadmap as FeatureRoadmap Component
    participant UI as UI Components

    User->>BlogShell: Navigate to /roadmap
    BlogShell->>RoadmapShell: Load roadmap route
    RoadmapShell->>FeatureRoadmap: Embed roadmap feature
    FeatureRoadmap->>UI: Render nodes and layers
    UI-->>FeatureRoadmap: Return rendered SVG nodes
    RoadmapShell->>User: Display complete roadmap
Loading

Suggested reviewers

  • DDonochVA

Poem

I'm a rabbit, hopping with delight,
New roadmap features in my sight!
From configs to components, neatly laid,
SVG wonders in every cascade.
With routes and tests so perfectly spun,
I celebrate the changes—oh what fun! 🐇✨
Hop along, enjoy the code run!


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@DamianBrzezinskiHoA DamianBrzezinskiHoA changed the title Feat/angular roadmap svg zoom Feat/angular-roadmap-svg-zoom Apr 7, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (18)
libs/blog/roadmap/feature-roadmap/src/lib/slice.pipes.ts (2)

3-11: Consider adding standalone: true to the pipe decorator

If you're using Angular 14+ and want to make this pipe more reusable, you can add standalone: true to the pipe decorator. This allows importing the pipe directly into components without needing to include it in a module.

@Pipe({
  name: 'leftSlice',
+  standalone: true,
})

13-21: Consider adding standalone: true to the pipe decorator

If you're using Angular 14+ and want to make this pipe more reusable, you can add standalone: true to the pipe decorator. This allows importing the pipe directly into components without needing to include it in a module.

@Pipe({
  name: 'rightSlice',
+  standalone: true,
})
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-secondary-node.component.ts (1)

9-11: Consider extracting hardcoded colors to design tokens

The inline style block contains hardcoded color values. For better maintainability and theming support, consider extracting these colors to a shared design token system or SCSS variables.

-      style="
-      --primary-color: #B3004A; --secondary-color: #66002B; --gradient-color: #481CAB; --on-hover-border-1: #923CFF; --on-hover-border-2: #FF006A"
+      [style]="roadmapNodeColors"

You could then define these colors in the component class or better yet, in a shared service:

roadmapNodeColors = {
  '--primary-color': '#B3004A',
  '--secondary-color': '#66002B',
  '--gradient-color': '#481CAB',
  '--on-hover-border-1': '#923CFF',
  '--on-hover-border-2': '#FF006A'
};
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-angular-love-node.component.ts (2)

5-21: Consider consolidating node components to reduce duplication

This component has significant template and style duplication with UiRoadmapSecondaryNodeComponent and UiRoadmapPrimaryNodeComponent. The main differences are styling properties like margin size, text size, and background gradient.

Consider creating a base component that accepts configuration for these styling differences:

@Component({
  selector: 'al-ui-roadmap-node',
  template: `
    <div
      class="roadmap-hover-border-gradient relative w-fit text-nowrap rounded-lg bg-[#FDF5FD] text-[#FDF5FD]"
      [style]="styleVars"
    >
      <div
        class="relative z-10 rounded-lg px-6 py-4"
        [ngClass]="config.margin"
        [ngStyle]="backgroundStyle"
      >
        <div [ngClass]="config.textSize">{{ node().title }}</div>
      </div>
    </div>
  `,
  styleUrls: ['./roadmap-hover-border-gradient.scss'],
})
export class UiRoadmapNodeComponent {
  readonly node = input.required<RoadmapNode>();
  @Input() config: NodeConfig = defaultConfig;
  
  get styleVars() {
    return {
      '--primary-color': '#B3004A',
      '--secondary-color': '#66002B',
      '--gradient-color': '#481CAB',
      '--on-hover-border-1': '#923CFF',
      '--on-hover-border-2': '#FF006A'
    };
  }
  
  get backgroundStyle() {
    return this.config.useGradient 
      ? { 'background': 'linear-gradient(to right, var(--secondary-color), var(--gradient-color))' }
      : { 'background': 'var(--' + this.config.backgroundColor + ')' };
  }
}

// Then create simple wrapper components for the specific node types

14-14: Note the duplicate space in class definition

There are two consecutive spaces between rounded-lg and bg-gradient-to-r in the class attribute. While this doesn't affect functionality, it's a minor styling inconsistency.

-        class="relative z-10 m-[4px] rounded-lg  bg-gradient-to-r from-[--secondary-color] to-[--gradient-color] px-6 py-4"
+        class="relative z-10 m-[4px] rounded-lg bg-gradient-to-r from-[--secondary-color] to-[--gradient-color] px-6 py-4"
libs/blog/shell/feature-shell-web/src/lib/blog-shell.routes.ts (1)

24-30: Consider adding SEO data for the roadmap route

The roadmap route is missing SEO data that's present on most other routes in the file. This could affect search engine visibility for this feature.

  {
    path: 'roadmap',
    loadComponent: async () =>
      await import('./roadmap-shell.component').then(
        (m) => m.RoadmapShellComponent,
      ),
+   data: {
+     seo: { title: 'seo.roadmap' },
+   },
  },
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-primary-node.component.ts (1)

8-18: Consider extracting hard-coded colors and styles.

The template includes hard-coded CSS variables and styling. For better maintainability and theme support, consider extracting these color values to a shared constants file or theme variables.

- <div
-   class="roadmap-hover-border-gradient relative w-fit text-nowrap rounded-lg bg-[#FDF5FD] text-[#FDF5FD]"
-   style="
-   --primary-color: #B3004A; --secondary-color: #66002B; --gradient-color: #481CAB; --on-hover-border-1: #923CFF; --on-hover-border-2: #FF006A"
- >
+ <div
+   class="roadmap-hover-border-gradient relative w-fit text-nowrap rounded-lg bg-[#FDF5FD] text-[#FDF5FD]"
+   [ngClass]="themeClass"
+ >

Consider creating a shared theme service or constants file for these values across all roadmap node components.

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

5-34: Consider extracting the template to a separate HTML file

The inline template is becoming quite complex. For better maintainability and code organization, consider moving it to a separate HTML file.


28-32: Avoid hard-coded color values in the component

The hard-coded CSS color values in the host binding should ideally be moved to a centralized theme configuration to maintain consistency across components and enable easier theming changes.


5-5: Consider adding OnPush change detection

For better performance, consider adding changeDetection: ChangeDetectionStrategy.OnPush to the component decorator since you're using signals which work well with OnPush change detection.

-@Component({
+@Component({
+  changeDetection: ChangeDetectionStrategy.OnPush,
   selector: 'al-ui-roadmap-cluster',
libs/blog/roadmap/feature-roadmap/src/lib/ui/roadmap-hover-border-gradient.scss (3)

9-13: Consider optimizing the pseudo-element dimensions

The fixed 2000px size for the pseudo-element is very large and might be excessive. Consider using a percentage-based or calculated size that scales with the element rather than a fixed pixel value.

-    width: 2000px;
-    height: 2000px;
-    top: calc(50% - 1000px);
-    left: calc(50% - 1000px);
+    width: 300%;
+    height: 300%;
+    top: -100%;
+    left: -100%;

13-13: Use CSS variables for consistent colors

The hardcoded color values (#ff006a, #923cff) should be replaced with CSS variables to maintain consistency with the component's use of variables for theming.

-    background: conic-gradient(#ff006a, #923cff, #ff006a);
+    background: conic-gradient(var(--on-hover-border-2), var(--on-hover-border-1), var(--on-hover-border-2));

20-22: Optimize animation performance

For better performance, consider adding the will-change: transform property to hint the browser about the upcoming animation. Also, consider using the transform property exclusively for animations as it's often hardware-accelerated.

  &:not(.cluster-node):hover::before {
    opacity: 1;
    animation: rotate 1s linear infinite;
+    will-change: transform;
  }
libs/blog/roadmap/feature-roadmap/src/lib/secondary-arrow.pipe.ts (1)

11-31: Consider clarifying arc logic and adding tests.

This arrow path generation is clear, but negative or large horizontalShift values may cause unexpected arcs. Consider adding tests to verify correct arrow shape edges for different input ranges.

libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.html (1)

52-105: Validate absolute positioning offset logic.

These inline positions (e.g. style="position: absolute") and top/left coordinates assume certain container dimensions. If sizes change at runtime, arrow lines might become misaligned. Regularly test on different screen sizes or dynamic roadmap data.

libs/blog/shell/feature-shell-web/src/lib/roadmap-shell.component.ts (2)

41-60: Unused adBannerVisible value.

Since adBannerVisible always returns false, the layout offset logic in the effect might never apply. Consider either removing this unused signal or completing its implementation.


80-88: Temporary solution note.

A TODO indicates that banner layout logic is a temporary workaround. You might consider creating a dedicated service or stable approach for controlling viewport offset to avoid potential tech debt.

libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.ts (1)

56-99: Consider externalizing roadmap data.

Storing nodesDto data inline is convenient for a prototype. However, pulling this data from a config file or service can improve maintainability and clarity once this roadmap grows more complex.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef2cd14 and 5ff89ba.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (25)
  • libs/blog/roadmap/feature-roadmap/.eslintrc.json (1 hunks)
  • libs/blog/roadmap/feature-roadmap/README.md (1 hunks)
  • libs/blog/roadmap/feature-roadmap/jest.config.ts (1 hunks)
  • libs/blog/roadmap/feature-roadmap/project.json (1 hunks)
  • libs/blog/roadmap/feature-roadmap/src/index.ts (1 hunks)
  • libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.html (1 hunks)
  • libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.scss (1 hunks)
  • libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.spec.ts (1 hunks)
  • libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.ts (1 hunks)
  • libs/blog/roadmap/feature-roadmap/src/lib/secondary-arrow.pipe.ts (1 hunks)
  • libs/blog/roadmap/feature-roadmap/src/lib/slice.pipes.ts (1 hunks)
  • libs/blog/roadmap/feature-roadmap/src/lib/ui/roadmap-hover-border-gradient.scss (1 hunks)
  • libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-angular-love-node.component.ts (1 hunks)
  • libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-cluster.component.ts (1 hunks)
  • libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-primary-node.component.ts (1 hunks)
  • libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-secondary-node.component.ts (1 hunks)
  • libs/blog/roadmap/feature-roadmap/src/test-setup.ts (1 hunks)
  • libs/blog/roadmap/feature-roadmap/tsconfig.json (1 hunks)
  • libs/blog/roadmap/feature-roadmap/tsconfig.lib.json (1 hunks)
  • libs/blog/roadmap/feature-roadmap/tsconfig.spec.json (1 hunks)
  • libs/blog/shell/feature-shell-web/src/lib/blog-shell.routes.ts (1 hunks)
  • libs/blog/shell/feature-shell-web/src/lib/roadmap-shell.component.ts (1 hunks)
  • libs/blog/shell/feature-shell-web/src/lib/root-shell.component.ts (1 hunks)
  • package.json (1 hunks)
  • tsconfig.base.json (1 hunks)
🧰 Additional context used
🧬 Code Definitions (4)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-secondary-node.component.ts (3)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-primary-node.component.ts (1)
  • Component (5-24)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-angular-love-node.component.ts (1)
  • Component (5-24)
libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.ts (2)
  • Component (40-211)
  • RoadmapNode (24-28)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-primary-node.component.ts (4)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-cluster.component.ts (1)
  • Component (5-37)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-angular-love-node.component.ts (1)
  • Component (5-24)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-secondary-node.component.ts (1)
  • Component (5-24)
libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.ts (2)
  • Component (40-211)
  • RoadmapNode (24-28)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-angular-love-node.component.ts (3)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-primary-node.component.ts (1)
  • Component (5-24)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-secondary-node.component.ts (1)
  • Component (5-24)
libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.ts (2)
  • Component (40-211)
  • RoadmapNode (24-28)
libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.ts (4)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-cluster.component.ts (1)
  • Component (5-37)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-primary-node.component.ts (1)
  • Component (5-24)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-angular-love-node.component.ts (1)
  • Component (5-24)
libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-secondary-node.component.ts (1)
  • Component (5-24)
🪛 Biome (1.9.4)
libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.ts

[error] 103-103: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)


[error] 158-158: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)


[error] 177-177: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

🔇 Additional comments (29)
libs/blog/roadmap/feature-roadmap/src/index.ts (1)

1-1: Export Re-Export Verified.
This export statement correctly re-exports all public members from the feature-roadmap.component module, streamlining imports for downstream modules.

package.json (1)

66-66: SVG-Pan-Zoom Dependency Added.
The addition of the "svg-pan-zoom": "^3.6.2" dependency introduces the necessary SVG manipulation features for the roadmap component. Please ensure that you periodically verify the security and compatibility status of this dependency.

libs/blog/roadmap/feature-roadmap/README.md (1)

1-8: New README Documentation for Feature-Roadmap.
The README clearly outlines the purpose of the library and provides concise instructions for running unit tests with nx test feature-roadmap. Expanding it in the future with usage examples or further documentation may benefit users.

libs/blog/shell/feature-shell-web/src/lib/root-shell.component.ts (1)

57-59: Host Styling Added for Layout Consistency.
The new host property assigning the class 'flex flex-col min-h-screen' ensures that the component maintains a full-height flex layout—which should contribute positively to the overall UI consistency.

libs/blog/roadmap/feature-roadmap/src/test-setup.ts (1)

1-7: Test Environment Setup Configured Correctly.
The test setup utilizing setupZoneTestEnv with both errorOnUnknownElements and errorOnUnknownProperties set to true is a robust configuration for catching template errors early during testing.

libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.scss (1)

1-12: Animation implementation looks good

The fadeIn animation is well-implemented with a smooth 1-second ease-in-out transition from opacity 0 to 1. This provides a nice visual effect when the roadmap container is rendered.

tsconfig.base.json (1)

191-193: Path mapping correctly configured

The path mapping for the new feature-roadmap module follows the established pattern in the project, enabling proper module resolution through the alias.

libs/blog/roadmap/feature-roadmap/project.json (1)

1-20: Project configuration looks good

The configuration follows the standard NX workspace pattern for Angular libraries, with appropriate tags and correctly configured test and lint targets.

libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-secondary-node.component.ts (2)

5-21: Well-structured component using appropriate styling techniques

The component's template uses a combination of Tailwind CSS classes and CSS variables for styling, which provides flexibility. The hover gradient effect is applied consistently with other roadmap node components.


22-24: Input property correctly implemented with required modifier

The component properly uses Angular's input signal with the required modifier to ensure the node data is provided when using this component.

libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-angular-love-node.component.ts (1)

22-24: Input property correctly implemented with required modifier

The component properly uses Angular's input signal with the required modifier, ensuring the node data is provided.

libs/blog/shell/feature-shell-web/src/lib/blog-shell.routes.ts (2)

24-30: Route placement places roadmap outside the main shell

Note that the roadmap route is configured to exist outside of the RootShellComponent, unlike most other routes. This means it won't inherit the layout and UI elements from the root shell. Ensure this is intentional, as it will create a different user experience compared to other sections of the application.


26-29: Properly implemented lazy loading for the roadmap component

The route correctly uses async/await with the import() syntax for lazy loading, which will help with initial load performance by only loading the roadmap feature when it's needed.

libs/blog/roadmap/feature-roadmap/tsconfig.lib.json (1)

1-17: Standard TypeScript library configuration

The TypeScript configuration follows standard practices for an Angular library within a monorepo structure. It correctly:

  • Extends the base configuration
  • Sets up declaration files and source maps
  • Excludes test files from the library build
  • Includes all TypeScript files in the source directory
libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.spec.ts (1)

1-22: Basic test structure looks good but could be enhanced.

This is a minimal test file that verifies the component can be created, which is a good starting point. Consider expanding the test suite to cover more functionality as the component evolves.

libs/blog/roadmap/feature-roadmap/src/lib/ui/ui-roadmap-primary-node.component.ts (1)

22-24: Input declaration looks good.

The use of input.required<RoadmapNode>() is a modern approach for declaring required inputs in Angular.

libs/blog/roadmap/feature-roadmap/.eslintrc.json (1)

1-36: ESLint configuration follows Angular best practices.

The ESLint configuration properly enforces consistent naming conventions with the 'al' prefix. Component selectors use kebab-case and directive selectors use camelCase, which aligns with Angular style guidelines.

libs/blog/roadmap/feature-roadmap/jest.config.ts (1)

1-21: Jest configuration looks good.

The Jest configuration properly sets up everything needed for Angular component testing, including the necessary transforms and serializers.

libs/blog/roadmap/feature-roadmap/tsconfig.spec.json (1)

1-16: Configuration looks appropriate for Jest testing

The TypeScript configuration for tests is correctly set up with CommonJS module system, ES2016 target, and proper type definitions for Jest and Node. The file patterns for tests also follow Angular conventions.

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

14-14: Optimize the trackBy function for better performance

The current trackBy is using clusterNode.id which is good, but ensure this id is stable and unique for optimal rendering performance.


36-36: Good use of the required input API

The component correctly uses Angular's newer signal-based input API with required validation to ensure the cluster data is provided.

libs/blog/roadmap/feature-roadmap/src/lib/ui/roadmap-hover-border-gradient.scss (1)

16-16: Be cautious with z-index values

The z-index of 1 might cause layering issues with other components. Consider implementing a consistent z-index strategy across the application to prevent unexpected stacking context issues.

libs/blog/roadmap/feature-roadmap/tsconfig.json (1)

1-28: Well-configured TypeScript settings with strict type checking

The TypeScript configuration is appropriately set up with strict type checking enabled, which will help catch potential errors early in development. The Angular compiler options correctly enforce strict template type checking as well.

libs/blog/roadmap/feature-roadmap/src/lib/secondary-arrow.pipe.ts (2)

1-3: Good use of Angular pipe boilerplate.

The import declarations and pipe metadata are straightforward and adhere to Angular convention.


7-9: Parameter default assignment is succinct.

Using withArc = true as a default parameter keeps the function flexible without cluttering the method signature.

libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.html (2)

1-6: Adopt consistent SVG namespace usage.

While xmlns:svg="http://www.w3.org/1999/html" works, it looks somewhat unconventional for an SVG container. Verify if it’s the intended namespace or if you should swap to the standard "http://www.w3.org/2000/svg".


17-49: Efficient @for iteration with track.

Using @for (layer of roadmapLayers(); track layer.parentNode.id) is good for performance. Ensure each unique layer.parentNode.id remains stable if data changes.

libs/blog/shell/feature-shell-web/src/lib/roadmap-shell.component.ts (1)

18-30: Simple and clean template structure.

The template integrates the header, roadmap, and footer well. The approach is readable and straightforward.

libs/blog/roadmap/feature-roadmap/src/lib/feature-roadmap.component.ts (1)

101-210: Roadmap layering logic looks robust.

The layered approach is coherent and methodically handles cluster nodes vs. primary nodes. Great job in ensuring cluster child ordering with previousNodeId.

🧰 Tools
🪛 Biome (1.9.4)

[error] 103-103: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)


[error] 158-158: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)


[error] 177-177: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

Comment on lines 1 to 21
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'leftSlice',
})
export class LeftSlicePipe implements PipeTransform {
transform<T>(value: T[]): T[] {
const halfLength = Math.ceil(value.length / 2);
return value.slice(0, halfLength);
}
}

@Pipe({
name: 'rightSlice',
})
export class RightSlicePipe implements PipeTransform {
transform<T>(value: T[]): T[] {
const halfLength = Math.ceil(value.length / 2);
return value.slice(halfLength);
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider adjusting the slicing logic for odd-length arrays

The pipes are well-typed with generics, but there's a potential issue with how they handle odd-length arrays. When an array has an odd number of elements:

  • LeftSlicePipe will return the larger half (due to Math.ceil)
  • RightSlicePipe will return the smaller half

This could cause unexpected behavior if these pipes are used together to split an array.

Consider one of these solutions:

@Pipe({
  name: 'rightSlice',
})
export class RightSlicePipe implements PipeTransform {
  transform<T>(value: T[]): T[] {
-    const halfLength = Math.ceil(value.length / 2);
+    const halfLength = Math.floor(value.length / 2);
    return value.slice(halfLength);
  }
}

Or for completely equal division (some overlap for odd lengths):

@Pipe({
  name: 'leftSlice',
})
export class LeftSlicePipe implements PipeTransform {
  transform<T>(value: T[]): T[] {
-    const halfLength = Math.ceil(value.length / 2);
+    const halfLength = Math.floor(value.length / 2);
    return value.slice(0, halfLength);
  }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'leftSlice',
})
export class LeftSlicePipe implements PipeTransform {
transform<T>(value: T[]): T[] {
const halfLength = Math.ceil(value.length / 2);
return value.slice(0, halfLength);
}
}
@Pipe({
name: 'rightSlice',
})
export class RightSlicePipe implements PipeTransform {
transform<T>(value: T[]): T[] {
const halfLength = Math.ceil(value.length / 2);
return value.slice(halfLength);
}
}
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'leftSlice',
})
export class LeftSlicePipe implements PipeTransform {
transform<T>(value: T[]): T[] {
const halfLength = Math.ceil(value.length / 2);
return value.slice(0, halfLength);
}
}
@Pipe({
name: 'rightSlice',
})
export class RightSlicePipe implements PipeTransform {
transform<T>(value: T[]): T[] {
const halfLength = Math.floor(value.length / 2);
return value.slice(halfLength);
}
}

Object.entries(clusterMap).forEach(([clusterNodeId, childrenNodeIds]) => {
const previousClusterNodeIdToNodeIdMap = childrenNodeIds.reduce(
(acc, primaryNodeId) => ({
...acc,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid repeated spreading in clusterMap.

Again, consider directly assigning properties to the accumulator object rather than spreading to prevent repeated copying.

🧰 Tools
🪛 Biome (1.9.4)

[error] 158-158: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

// setup layers
const previousLayerNodeIdToNodeIdMap = Object.keys(layerMap).reduce(
(acc, primaryNodeId) => ({
...acc,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Likewise, prefer direct assignment in reduce.

Repeated usage of ...acc in .reduce() can degrade performance in large data sets. In-place updates yield more efficient time complexity.

🧰 Tools
🪛 Biome (1.9.4)

[error] 177-177: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

@DamianBrzezinskiHoA DamianBrzezinskiHoA force-pushed the feat/angular-roadmap-svg-zoom branch from fe73f1d to 4bc6287 Compare April 9, 2025 11:23
@DamianBrzezinskiHoA DamianBrzezinskiHoA changed the base branch from main to feat/angular-roadmap April 9, 2025 11:27
@valueadd-robot
Copy link

PR is detected, will deploy to dev environment

@valueadd-robot
Copy link

Deployed to dev environment
Branch: feat/angular-roadmap-svg-zoom
BFF URL: https://33d0e71c-blog-bff-dev.contact-ef8.workers.dev
Deploy URL: https://142bea6c.angular-love-client.pages.dev
Alias URL: https://feat-angular-roadmap-svg-zoo.angular-love-client.pages.dev

@DamianBrzezinskiHoA DamianBrzezinskiHoA force-pushed the feat/angular-roadmap-svg-zoom branch from 4bc6287 to a86f645 Compare April 9, 2025 11:31
@valueadd-robot
Copy link

PR is detected, will deploy to dev environment

@valueadd-robot
Copy link

Deployed to dev environment
Branch: feat/angular-roadmap-svg-zoom
BFF URL: https://dca52d83-blog-bff-dev.contact-ef8.workers.dev
Deploy URL: https://34332fcd.angular-love-client.pages.dev
Alias URL: https://feat-angular-roadmap-svg-zoo.angular-love-client.pages.dev

@DamianBrzezinskiHoA DamianBrzezinskiHoA merged commit 9a78f90 into feat/angular-roadmap Apr 10, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants