Skip to content

Implement shareable links to individual reviews on company pages - #105

Merged
maximgorbatyuk merged 4 commits into
mainfrom
copilot/add-review-link-to-company-page
Oct 20, 2025
Merged

maximgorbatyuk merged 4 commits into
mainfrom
copilot/add-review-link-to-company-page

Conversation

Copilot AI commented Oct 20, 2025 •

Copy link
Copy Markdown
Contributor

Overview

This PR implements the ability to share direct links to specific reviews on company pages. Users can now copy a link to any review and share it with others. When someone opens that link, the page automatically scrolls to the specific review after the data loads asynchronously.

Problem

Previously, there was no way to link directly to a specific review on a company page. Users could only share the company page URL, forcing recipients to manually search through all reviews to find the one being referenced.

Solution

Added anchor-based navigation with the following features:

1. Copy Link Functionality

  • Added a link icon button (🔗) next to the vote buttons on each review
  • Clicking the button copies a shareable URL to the clipboard: https://example.com/companies/{companyId}#review-{reviewId}
  • Success/error feedback messages inform users of the copy status
  • Includes fallback for browsers without clipboard API support

2. Auto-scroll Navigation

  • Each review now has a unique anchor ID: review-{reviewId}
  • When opening a URL with a review fragment, the page:
    1. Loads company data asynchronously
    2. Waits 100ms for DOM to fully render
    3. Automatically scrolls to the targeted review using Angular's ViewportScroller

3. Analytics Integration

  • Tracks link copy events via Google Analytics (company_review_link_copied)
  • Helps monitor feature adoption and user engagement

Technical Implementation

Key changes:

  • Injected ViewportScroller into CompanyPageComponent for scroll handling
  • Subscribed to ActivatedRoute.fragment to detect review anchors in URL
  • Implemented copyReviewLink() method with clipboard API and fallback
  • Added copyLink event emitter to CompanyReviewBlockComponent
  • Applied anchor IDs to review container divs in the template

Pattern consistency: Follows the existing scrolling pattern used in telegram-bot.component.ts

Browser Compatibility

  • Modern browsers: Full clipboard API support with automatic copy
  • Legacy browsers: Fallback message guides users to use browser's native share functionality
  • All browsers: Anchor navigation works using standard HTML fragments

Testing

  • ✅ All 192 existing tests pass
  • ✅ Added ViewportScroller mock to test configuration
  • ✅ Linter passes with no issues
  • ✅ CodeQL security scan: 0 vulnerabilities
  • ✅ Build successful

Screenshots

The link button appears as a link icon next to the existing vote buttons:

Review #1
Rating: 4.5 ⭐⭐⭐⭐⭐
Pros: Great company...
Date: 01.10.2024    [🔗] [👍] [👎]
                      ↑
                   New button

Future Enhancements

Potential improvements for future iterations:

  • Visual highlight animation when scrolling to a review
  • Social media share buttons (Twitter, LinkedIn, etc.)
  • Option to share with specific review sections highlighted

Closes #[issue_number]

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • accounts.google.com
    • Triggering command: /opt/google/chrome/chrome --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=4066 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/karma-93875896 --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,2654360719313914957,3664003978613292626,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome --user-data-dir=/tmp/karma-93875896 --enable-automation --no-default-browser-check --no-first-run --disable-default-apps --disable-popup-blocking --disable-translate --disable-REDACTED-timer-throttling --disable-renderer-REDACTEDing --disable-device-discovery-notifications --no-sandbox --headless --disable-gpu --disable-translate --disable-extensions --headless --disable-gpu --disable-dev-shm-usage --remote-debugging-port=9222 --noerrdialogs --ozone-platform=headless --ozone-override-screen-size=800,600 --use-angle=swiftshader-webgl http://localhost:9876/?id=93875896 (dns block)
  • android.clients.google.com
    • Triggering command: /opt/google/chrome/chrome --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=4066 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/karma-93875896 --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,2654360719313914957,3664003978613292626,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome --user-data-dir=/tmp/karma-93875896 --enable-automation --no-default-browser-check --no-first-run --disable-default-apps --disable-popup-blocking --disable-translate --disable-REDACTED-timer-throttling --disable-renderer-REDACTEDing --disable-device-discovery-notifications --no-sandbox --headless --disable-gpu --disable-translate --disable-extensions --headless --disable-gpu --disable-dev-shm-usage --remote-debugging-port=9222 --noerrdialogs --ozone-platform=headless --ozone-override-screen-size=800,600 --use-angle=swiftshader-webgl http://localhost:9876/?id=93875896 (dns block)
  • clients2.google.com
    • Triggering command: /opt/google/chrome/chrome --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=4066 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/karma-93875896 --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,2654360719313914957,3664003978613292626,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome --user-data-dir=/tmp/karma-93875896 --enable-automation --no-default-browser-check --no-first-run --disable-default-apps --disable-popup-blocking --disable-translate --disable-REDACTED-timer-throttling --disable-renderer-REDACTEDing --disable-device-discovery-notifications --no-sandbox --headless --disable-gpu --disable-translate --disable-extensions --headless --disable-gpu --disable-dev-shm-usage --remote-debugging-port=9222 --noerrdialogs --ozone-platform=headless --ozone-override-screen-size=800,600 --use-angle=swiftshader-webgl http://localhost:9876/?id=93875896 (dns block)
  • clientservices.googleapis.com
    • Triggering command: /opt/google/chrome/chrome --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=4066 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/karma-93875896 --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,2654360719313914957,3664003978613292626,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome --user-data-dir=/tmp/karma-93875896 --enable-automation --no-default-browser-check --no-first-run --disable-default-apps --disable-popup-blocking --disable-translate --disable-REDACTED-timer-throttling --disable-renderer-REDACTEDing --disable-device-discovery-notifications --no-sandbox --headless --disable-gpu --disable-translate --disable-extensions --headless --disable-gpu --disable-dev-shm-usage --remote-debugging-port=9222 --noerrdialogs --ozone-platform=headless --ozone-override-screen-size=800,600 --use-angle=swiftshader-webgl http://localhost:9876/?id=93875896 (dns block)
  • googlechromelabs.github.io
    • Triggering command: node install.mjs (dns block)
  • https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.53/linux64/chrome-headless-shell-linux64.zip
    • Triggering command: node install.mjs (http block)
  • redirector.gvt1.com
    • Triggering command: /opt/google/chrome/chrome --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=4066 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/karma-93875896 --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,2654360719313914957,3664003978613292626,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome --user-data-dir=/tmp/karma-93875896 --enable-automation --no-default-browser-check --no-first-run --disable-default-apps --disable-popup-blocking --disable-translate --disable-REDACTED-timer-throttling --disable-renderer-REDACTEDing --disable-device-discovery-notifications --no-sandbox --headless --disable-gpu --disable-translate --disable-extensions --headless --disable-gpu --disable-dev-shm-usage --remote-debugging-port=9222 --noerrdialogs --ozone-platform=headless --ozone-override-screen-size=800,600 --use-angle=swiftshader-webgl http://localhost:9876/?id=93875896 (dns block)
  • safebrowsingohttpgateway.googleapis.com
    • Triggering command: /opt/google/chrome/chrome --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=4066 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/karma-93875896 --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,2654360719313914957,3664003978613292626,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome --user-data-dir=/tmp/karma-93875896 --enable-automation --no-default-browser-check --no-first-run --disable-default-apps --disable-popup-blocking --disable-translate --disable-REDACTED-timer-throttling --disable-renderer-REDACTEDing --disable-device-discovery-notifications --no-sandbox --headless --disable-gpu --disable-translate --disable-extensions --headless --disable-gpu --disable-dev-shm-usage --remote-debugging-port=9222 --noerrdialogs --ozone-platform=headless --ozone-override-screen-size=800,600 --use-angle=swiftshader-webgl http://localhost:9876/?id=93875896 (dns block)
  • techinterview.fra1.cdn.digitaloceanspaces.com
    • Triggering command: /opt/google/chrome/chrome --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=4066 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/karma-93875896 --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,2654360719313914957,3664003978613292626,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome --user-data-dir=/tmp/karma-93875896 --enable-automation --no-default-browser-check --no-first-run --disable-default-apps --disable-popup-blocking --disable-translate --disable-REDACTED-timer-throttling --disable-renderer-REDACTEDing --disable-device-discovery-notifications --no-sandbox --headless --disable-gpu --disable-translate --disable-extensions --headless --disable-gpu --disable-dev-shm-usage --remote-debugging-port=9222 --noerrdialogs --ozone-platform=headless --ozone-override-screen-size=800,600 --use-angle=swiftshader-webgl http://localhost:9876/?id=93875896 (dns block)
  • www.google.com
    • Triggering command: /opt/google/chrome/chrome --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=4066 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/karma-93875896 --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,2654360719313914957,3664003978613292626,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome --user-data-dir=/tmp/karma-93875896 --enable-automation --no-default-browser-check --no-first-run --disable-default-apps --disable-popup-blocking --disable-translate --disable-REDACTED-timer-throttling --disable-renderer-REDACTEDing --disable-device-discovery-notifications --no-sandbox --headless --disable-gpu --disable-translate --disable-extensions --headless --disable-gpu --disable-dev-shm-usage --remote-debugging-port=9222 --noerrdialogs --ozone-platform=headless --ozone-override-screen-size=800,600 --use-angle=swiftshader-webgl http://localhost:9876/?id=93875896 (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Implement link to the review on the company page</issue_title>
<issue_description>There is a page with company details and reviews on it. We need to add a link to the concrete review that might be shared to someone else. The data is being loaded asynchronously, so the link should be implemented taking into account this fact. After the link with review anchor is opened, the page should be scrolled to the review.</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #104


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits October 20, 2025 10:03
Co-authored-by: maximgorbatyuk <13348685+maximgorbatyuk@users.noreply.github.com>
…null safety

Co-authored-by: maximgorbatyuk <13348685+maximgorbatyuk@users.noreply.github.com>
Co-authored-by: maximgorbatyuk <13348685+maximgorbatyuk@users.noreply.github.com>
Copilot AI changed the title [WIP] Add link to review on company page Implement shareable links to individual reviews on company pages Oct 20, 2025
Copilot AI requested a review from maximgorbatyuk October 20, 2025 10:13
@maximgorbatyuk
maximgorbatyuk marked this pull request as ready for review October 20, 2025 10:29
@coderabbitai

coderabbitai Bot commented Oct 20, 2025

Copy link
Copy Markdown

Important

Review skipped

Bot user detected.

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.


Comment @coderabbitai help to get the list of available commands and usage tips.

@maximgorbatyuk
maximgorbatyuk merged commit e9a4166 into main Oct 20, 2025
2 checks passed
@maximgorbatyuk
maximgorbatyuk deleted the copilot/add-review-link-to-company-page branch October 21, 2025 07:10
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.

Implement link to the review on the company page

2 participants