Skip to content
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

feat: support diff functions for some properties #5279

Closed
wants to merge 5 commits into from

Conversation

WTIFS
Copy link
Contributor

@WTIFS WTIFS commented Nov 15, 2024

What's the purpose of this PR

The diff function doesn't work for properties currently. We'd like to compare the properties in different cluster or branch.

当前 apollo 页面上的 diff 功能不支持 properties 格式的配置,不便于对比配置。 我们希望支持 properties 格式的 diff 高亮功能

Which issue(s) this PR fixes:

Fixes #

Brief changelog

  1. compare with previous version when doing a grayscale release
  2. compare with master/released version when doing a grayscale full release
  3. compare with released version when doing a release
  4. support diff of properties when comparing between clusters
  5. support diff of properties in release history page

pics:

  1. compare with previous version when doing a gray scale release
image
  1. compare with master/released version when doing a gray scale full release
image
  1. compare with released version when doing a release
image
  1. support diff of properties when comparing between clusters
image
  1. support diff of properties in release history page:
image

Follow this checklist to help us incorporate your contribution quickly and easily:

  • Read the Contributing Guide before making this pull request.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Write necessary unit tests to verify the code.
  • Run mvn clean test to make sure this pull request doesn't break anything.
  • Update the CHANGES log.

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced table structure for displaying differences in the configuration settings.
    • Introduced a new component for visual text comparison of configuration changes.
  • Improvements

    • Updated Chinese localization for clarity in publishing status messages.
    • Enhanced styling for better layout control in tables and text elements.
    • Refined logic for displaying elements in the release modal based on release type.
    • Improved rendering of diff outputs for better visibility of changes.
  • Bug Fixes

    • Refined logic for displaying release process tables, improving clarity and functionality.

@dosubot dosubot bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Nov 15, 2024
Copy link
Contributor

coderabbitai bot commented Nov 15, 2024

Walkthrough

The changes in this pull request involve modifications to several files related to the presentation and functionality of the Apollo configuration center. Key updates include enhancements to the HTML structure and AngularJS bindings in diff.html, localization updates in zh-CN.json, and improvements to the DiffConfigController.js for better handling of synchronization data. Additionally, new CSS classes were introduced in common-style.css to improve layout control, and the release modal's HTML was refined for better user interface clarity.

Changes

File Path Change Summary
apollo-portal/src/main/resources/static/config/diff.html Enhanced table structure with a new class table-fixed, updated column widths, simplified value logic using compositedKey, and added <apollodiff> component for text mode differences.
apollo-portal/src/main/resources/static/i18n/zh-CN.json Updated string values for publishing status messages to improve clarity, with no changes to the JSON structure.
apollo-portal/src/main/resources/static/scripts/controller/config/DiffConfigController.js Modified parseSyncSourceData to include firstClusterKey for tracking the first selected cluster's composited key.
apollo-portal/src/main/resources/static/styles/common-style.css Added new CSS classes .left-overflow and .table-fixed, and updated the .pre class for better layout control.
apollo-portal/src/main/resources/static/views/component/diff.html Updated <pre> tag to include an additional class for styling.
apollo-portal/src/main/resources/static/views/component/release-modal.html Enhanced the release modal with new HTML comments, updated table structures, added table-fixed class, and replaced ng-bind with apollodiff components for visual comparisons.
apollo-portal/src/main/resources/static/scripts/directive/diff-directive.js Modified makeDiff function to set display style of span elements to block, affecting how diffs are rendered.
apollo-portal/src/main/resources/static/config/history.html Updated table layout with table-fixed, adjusted column widths, and incorporated apollodiff for visual representation of changes.

Possibly related PRs

  • chore: typo fix #5272: This PR is unrelated to the main PR as it only addresses a typographical error in a different file and does not involve any changes to HTML structure, AngularJS bindings, or the logic for displaying differences.

Suggested labels

size:S, lgtm

Suggested reviewers

  • shoothzj

Poem

🐰 In the land of code where changes bloom,
A table fixed to chase away gloom.
With strings that shift and styles that play,
The diff brings clarity to our day.
So hop along, let differences show,
In the world of Apollo, we’ll continue to grow! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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 resolve resolve all the CodeRabbit review comments.
  • @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.

Copy link

CLA Assistant Lite bot:
Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request

Copy link
Contributor

@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: 1

🧹 Outside diff range and nitpick comments (8)
apollo-portal/src/main/resources/static/scripts/controller/config/DiffConfigController.js (2)

167-168: LGTM: Good addition of firstClusterKey for reference cluster tracking.

The addition of firstClusterKey to the syncData structure provides a clear reference point for cluster comparisons, which is essential for the new diff functionality.

Consider documenting the significance of firstClusterKey in the code comments, as it serves as a crucial reference point for the diff comparison logic.


175-175: Consider adding validation and extracting the key generation logic.

While the compositedKey implementation is correct, consider these improvements:

  1. Validate that env, clusterName, and namespaceName don't contain ':' to prevent parsing issues
  2. Extract the key generation into a reusable utility function for consistency
+ // Add to a utility service/file
+ function generateCompositedKey(env, clusterName, namespaceName) {
+   // Validate components don't contain separator
+   if ([env, clusterName, namespaceName].some(component => component.includes(':'))) {
+     throw new Error('Cluster components cannot contain ":"');
+   }
+   return `${env}:${clusterName}:${namespaceName}`;
+ }

- cluster.compositedKey = cluster.env + ':' + cluster.clusterName + ':' + cluster.namespaceName;
+ cluster.compositedKey = generateCompositedKey(cluster.env, cluster.clusterName, cluster.namespaceName);
apollo-portal/src/main/resources/static/config/diff.html (2)

130-134: LGTM! Consider adding ARIA attributes for better accessibility.

The table structure changes look good with proper width constraints and consistent class usage.

Consider adding ARIA attributes to improve accessibility:

-<table class="table table-bordered table-striped table-hover table-fixed" ng-show="isTableDiff">
+<table class="table table-bordered table-striped table-hover table-fixed" ng-show="isTableDiff" role="grid" aria-label="Configuration differences">

162-166: Consider adding error handling for text mode.

The text mode diff implementation looks good, but consider adding error handling for cases where originTextInfo might be undefined or malformed.

Add error handling:

-<apollodiff  ng-show="!isTableDiff" old-str="syncData.syncToNamespaces[0].originTextInfo"
+<apollodiff  ng-show="!isTableDiff && syncData.syncToNamespaces.length >= 2" old-str="syncData.syncToNamespaces[0].originTextInfo"
              new-str="syncData.syncToNamespaces[1].originTextInfo" apollo-id="'releaseStrDiff'">
</apollodiff>
+<div ng-show="!isTableDiff && syncData.syncToNamespaces.length < 2" class="alert alert-warning">
+  {{'Config.Diff.InsufficientClusters' | translate }}
+</div>
apollo-portal/src/main/resources/static/views/component/release-modal.html (2)

71-72: Consider translating Chinese comments to English for consistency

While the added section comments improve code organization, consider translating them to English to maintain consistency with the rest of the codebase and improve accessibility for international contributors:

  • "主版本发布" → "Main Version Release"
  • "灰度发布" → "Gray Release"
  • "灰度推全" → "Full Release from Gray"

Also applies to: 125-125, 177-178


Line range hint 1-300: Well-structured implementation of diff functionality

The changes effectively implement diff visualization across all three release types (normal, gray, and full release), with consistent patterns and clear separation. This aligns perfectly with the PR objectives of supporting property format comparisons across different scenarios.

A few architectural observations:

  1. The modal maintains clear separation between different release types
  2. The diff implementation is consistent across all views
  3. The UI provides clear visual feedback for configuration changes
apollo-portal/src/main/resources/static/styles/common-style.css (2)

1186-1187: Consider adding width constraints for better table layout control.

While the table-fixed class correctly sets the table layout to fixed, consider adding default or minimum column widths to prevent extremely narrow columns in the diff view.

 .table-fixed{
     table-layout: fixed;
+    min-width: 600px; /* Ensure minimum table width */
+    width: 100%; /* Fill available space */
 }

98-108: Architecture feedback: Well-structured CSS changes for diff functionality.

The CSS changes form a cohesive set of styles that work together to support property diff views:

  1. Pre-formatting for preserving whitespace
  2. Overflow handling for long lines
  3. Fixed table layout for consistent diff presentation

This layered approach to styling provides good separation of concerns and maintainability.

Also applies to: 1181-1184, 1186-1187

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between a90fb6b and 2abd7aa.

📒 Files selected for processing (6)
  • apollo-portal/src/main/resources/static/config/diff.html (2 hunks)
  • apollo-portal/src/main/resources/static/i18n/zh-CN.json (1 hunks)
  • apollo-portal/src/main/resources/static/scripts/controller/config/DiffConfigController.js (1 hunks)
  • apollo-portal/src/main/resources/static/styles/common-style.css (2 hunks)
  • apollo-portal/src/main/resources/static/views/component/diff.html (1 hunks)
  • apollo-portal/src/main/resources/static/views/component/release-modal.html (7 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apollo-portal/src/main/resources/static/views/component/diff.html
🔇 Additional comments (7)
apollo-portal/src/main/resources/static/config/diff.html (2)

157-157: LGTM! Comment display implementation is consistent.

The comment display logic properly handles undefined values and follows the same pattern as value comparison.


146-153: Verify the compositedKey generation across clusters.

The value comparison implementation looks good with proper fallback handling and diff highlighting.

Let's verify the compositedKey implementation in the controller:

✅ Verification successful

compositedKey implementation is correctly used for cluster comparison

The verification confirms that compositedKey is properly constructed from cluster attributes:

  • Composed as env:clusterName:namespaceName in DiffConfigController
  • Used consistently as a unique identifier for cluster comparison in the diff view
  • Properly initialized before being used in the sync data structure
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify compositedKey generation in DiffConfigController
ast-grep --pattern 'compositedKey = $$$' apollo-portal/src/main/resources/static/scripts/controller/config/DiffConfigController.js

Length of output: 132


Script:

#!/bin/bash
# Let's try a broader search for compositedKey usage and definition
rg -A 5 "compositedKey" apollo-portal/src/main/resources/static/scripts/controller/config/DiffConfigController.js

# Also search for cluster key related code
ast-grep --pattern 'cluster.$_ = $$$'

Length of output: 2487

apollo-portal/src/main/resources/static/views/component/release-modal.html (2)

82-82: LGTM! Good improvements to the diff visualization

The changes enhance the UI by:

  1. Adding fixed width for better table layout control
  2. Implementing the apollodiff component for visual comparison between old and new values

Also applies to: 112-113


188-188: Verify apollodiff component implementation

The changes look good and properly implement diff visualization for gray releases. Let's verify the apollodiff component implementation across the codebase.

Also applies to: 213-214

✅ Verification successful

Let me verify the apollodiff component definition itself with another script.


Let me check the actual implementation and template of the apollodiff component.


apollodiff component implementation is correct and properly used

The apollodiff directive is well-implemented with:

  • Proper scope isolation with two-way binding for oldStr, newStr, and apolloId
  • Correct diff visualization using JsDiff library
  • Consistent usage across the codebase with appropriate apollo-id prefixes:
    • 'unpublishedDiffPublished:' for unpublished vs published
    • 'grayDiffMaster:' for gray vs master version
    • 'releaseStrDiffWithMasterValue' for release vs master
    • 'releaseStrDiffWithPublishedValue' for release vs published
    • 'clusterDiff:' for cluster comparisons
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify apollodiff component implementation and usage

# Check apollodiff component definition
echo "Checking apollodiff component definition:"
fd -e js -e ts apollodiff

# Check apollodiff usage patterns
echo -e "\nChecking apollodiff usage patterns:"
rg -A 2 '<apollodiff\s+old-str=' --type html

Length of output: 2798


Script:

#!/bin/bash
# Search for apollodiff directive/component definition
ast-grep --pattern 'directive($_, "apollodiff")'

# Also check for any JS/TS files containing apollodiff implementation
rg -A 5 "apollodiff" --type js --type ts

Length of output: 1214


Script:

#!/bin/bash
# Check the directive implementation
echo "=== Checking diff directive implementation ==="
cat apollo-portal/src/main/resources/static/scripts/directive/diff-directive.js

# Check the diff component template
echo -e "\n=== Checking diff component template ==="
cat apollo-portal/src/main/resources/static/views/component/diff.html

Length of output: 3751

apollo-portal/src/main/resources/static/styles/common-style.css (2)

98-108: LGTM: Pre-formatting styles support property diff views.

The separation between pre and .pre classes allows for flexible handling of whitespace in different contexts, which is essential for properly displaying property file diffs.


1181-1184: LGTM: Overflow handling for long property lines.

The .left-overflow class appropriately handles horizontal scrolling while maintaining left alignment, which is crucial for displaying long property lines in diff views.

apollo-portal/src/main/resources/static/i18n/zh-CN.json (1)

294-294: LGTM! The translation changes improve clarity.

The changes to the translation strings better reflect the actual states:

  • "已发布的值" (published value) for PublishedValue is more accurate
  • "待发布的值" (value to be published) for NoPublishedValue is more logical

Also applies to: 297-297

syncData.syncToNamespaces.push(cluster);
}
});

syncData.firstClusterKey = selectedClusters[0].compositedKey;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add validation for selectedClusters array.

The current implementation assumes selectedClusters[0] exists, which could lead to runtime errors if the array is empty.

- syncData.firstClusterKey = selectedClusters[0].compositedKey;
+ syncData.firstClusterKey = selectedClusters.length > 0 ? selectedClusters[0].compositedKey : "";
📝 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
syncData.firstClusterKey = selectedClusters[0].compositedKey;
syncData.firstClusterKey = selectedClusters.length > 0 ? selectedClusters[0].compositedKey : "";

@nobodyiam
Copy link
Member

Thanks for adding this great feature. Please find some comments below:

  1. Could the diff format for non-JSON values be made clearer?
    image
    image

  2. Should we add the diff feature for grayscale release?
    image

Copy link
Contributor

@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: 0

🧹 Outside diff range and nitpick comments (1)
apollo-portal/src/main/resources/static/scripts/directive/diff-directive.js (1)

Line range hint 41-70: Consider enhancing diff visualization for properties format

While adding display: block improves the layout, consider these enhancements for better property diff visualization:

  1. Add specific CSS classes instead of inline styles for better maintainability
  2. Consider adding indentation for nested properties
  3. Add special handling for property key-value pairs to highlight changes in keys and values separately

This would better align with the PR's objective of supporting properties format configurations.

Example implementation:

                         color = part.added ? 'green' :
                             part.removed ? 'red' : 'grey';
                         span = document.createElement('span');
-                        span.style.color = color;
-                        span.style.display = 'block';
+                        span.className = `diff-line diff-${color}`;
                         pre = part.added ? '+' :
                             part.removed ? '-' : '';
-                        span.appendChild(document.createTextNode(pre + part.value));
+                        // Special handling for property format
+                        if (isPropertyFormat(part.value)) {
+                            const [key, value] = parseProperty(part.value);
+                            const keySpan = document.createElement('span');
+                            keySpan.className = 'diff-property-key';
+                            keySpan.textContent = pre + key;
+                            
+                            const valueSpan = document.createElement('span');
+                            valueSpan.className = 'diff-property-value';
+                            valueSpan.textContent = value;
+                            
+                            span.appendChild(keySpan);
+                            span.appendChild(valueSpan);
+                        } else {
+                            span.appendChild(document.createTextNode(pre + part.value));
+                        }

Add corresponding CSS:

.diff-line {
    display: block;
    padding: 2px 0;
}
.diff-green { color: green; }
.diff-red { color: red; }
.diff-grey { color: grey; }
.diff-property-key {
    font-weight: bold;
    margin-right: 8px;
}
.diff-property-value {
    font-family: monospace;
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 2abd7aa and d231d3f.

📒 Files selected for processing (3)
  • apollo-portal/src/main/resources/static/i18n/zh-CN.json (2 hunks)
  • apollo-portal/src/main/resources/static/scripts/directive/diff-directive.js (1 hunks)
  • apollo-portal/src/main/resources/static/views/component/release-modal.html (11 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apollo-portal/src/main/resources/static/i18n/zh-CN.json
  • apollo-portal/src/main/resources/static/views/component/release-modal.html
🔇 Additional comments (1)
apollo-portal/src/main/resources/static/scripts/directive/diff-directive.js (1)

63-63: ⚠️ Potential issue

Add missing semicolon

A semicolon is missing at the end of the statement.

Apply this diff to fix the syntax:

-                        span.style.display = 'block'
+                        span.style.display = 'block';

@WTIFS
Copy link
Contributor Author

WTIFS commented Nov 18, 2024

Thanks for adding this great feature. Please find some comments below:

  1. Could the diff format for non-JSON values be made clearer?
    image
    image
  2. Should we add the diff feature for grayscale release?
    image
  1. A display: block style has been added to the diff span, now the diff for strings will be seperated into different lines to make it clearer
  2. Yes the feature is now added to the grayscale release, too. Please take another look

@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Nov 20, 2024
Copy link
Contributor

@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: 0

🧹 Outside diff range and nitpick comments (1)
apollo-portal/src/main/resources/static/config/history.html (1)

191-198: Excellent implementation of visual diff component

The apollodiff component implementation effectively addresses the requirement for clearer property diffs. This change directly improves the user experience by providing visual difference comparisons.

Consider these enhancements for robustness:

  1. Add error handling for cases where diff generation might fail
  2. Enhance accessibility by adding ARIA attributes for screen readers

Add error handling and accessibility improvements:

 <td class="cursor-pointer left-overflow" width="35%"
     ng-click="showText(change.entity.secondEntity.value)">
     <span>
         <apollodiff  old-str="change.entity.firstEntity.value"
                     new-str="change.entity.secondEntity.value"
-                    apollo-id="'diff:' + change.entity.firstEntity.key">
+                    apollo-id="'diff:' + change.entity.firstEntity.key"
+                    role="region"
+                    aria-label="{{'Config.History.DiffViewer' | translate }}"
+                    ng-attr-aria-errormessage="{{ diffError ? 'diff-error-' + $id : undefined }}">
         </apollodiff>
+        <div ng-if="diffError" id="diff-error-{{$id}}" class="alert alert-danger">
+            {{'Config.History.DiffError' | translate }}
+        </div>
     </span>
 </td>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6ff3dec and f54cb51.

📒 Files selected for processing (2)
  • apollo-portal/src/main/resources/static/config/history.html (2 hunks)
  • apollo-portal/src/main/resources/static/i18n/zh-CN.json (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apollo-portal/src/main/resources/static/i18n/zh-CN.json
🔇 Additional comments (1)
apollo-portal/src/main/resources/static/config/history.html (1)

160-164: LGTM! Table layout improvements enhance readability

The addition of table-fixed class and explicit column widths provides better control over the table layout, ensuring consistent presentation of configuration changes.

@WTIFS
Copy link
Contributor Author

WTIFS commented Nov 20, 2024

@nobodyiam
Hi, I'm planning to put the diff into text modal instead of in the tables, as the diff looks too crowed in the table. I'll close this pull request and make a new one when it's ready.

@WTIFS WTIFS closed this Nov 20, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Nov 20, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
size:L This PR changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants