Skip to content

fix: [AH-2866]: Deletion statements updated at all 3 registry,package and version level#89

Open
abhinavcode wants to merge 3 commits into
mainfrom
AH-2866
Open

fix: [AH-2866]: Deletion statements updated at all 3 registry,package and version level#89
abhinavcode wants to merge 3 commits into
mainfrom
AH-2866

Conversation

@abhinavcode

@abhinavcode abhinavcode commented Feb 22, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • Bug Fixes

    • HTML-encoded characters now render correctly in delete confirmation modals for artifacts and repositories.
  • New Features

    • OCI package deletion supports digest-based confirmation for Docker and Helm packages.
  • UI/UX

    • Confirmation labels can show the specific item being confirmed when available.
    • Registry deletion prompts shortened for clearer, more concise text.

@coderabbitai

coderabbitai Bot commented Feb 22, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Adds HTML-entity decoding for displayed identifiers, uses decoded values as modal confirmation inputs, exposes a decode utility, extends version deletion to accept OCI digests, and updates the delete modal component to accept an optional input label value for augmented labels.

Changes

Cohort / File(s) Summary
Modal Component Enhancement
web/src/ar/components/Form/DeleteModalContent.tsx
Added optional inputLabelValue?: string, computed finalLabel that appends the value in parentheses when provided, and switched FormInput.Text to use finalLabel.
Artifact Delete Modal Hook
web/src/ar/pages/artifact-details/hooks/useDeleteArtifactModal/useDeleteArtifactModal.tsx
Imported and applied decodeHtmlEntities to artifactKey; passed decoded value as value and inputLabelValue to DeleteModalContent.
Repository Delete Modal Hook
web/src/ar/pages/repository-details/hooks/useDeleteRepositoryModal/useDeleteRepositoryModal.tsx
Imported and applied decodeHtmlEntities to repoKey; passed decoded value as value and inputLabelValue to DeleteModalContent.
Repository List Strings
web/src/ar/pages/repository-list/strings/strings.en.yaml
Adjusted delete modal prompt text (shortened registry prompt) and added softDeleteModal input label/placeholder fields.
Version Deletion: UI + Hook
web/src/ar/pages/version-details/components/VersionActions/DeleteVersionMenuItem.tsx, web/src/ar/pages/version-details/hooks/useDeleteVersionModal.tsx
Added digest prop propagation and packageType handling; imported RepositoryPackageType and decodeHtmlEntities; choose confirmation display value (decoded digest for OCI Docker/Helm when present, otherwise decoded version key) and pass as value/inputLabelValue.
Utility Export
web/src/ar/common/utils.ts
Re-exported decodeHtmlEntities from ./utils/decodeHtmlEntities.
New Utility Implementation
web/src/ar/common/utils/decodeHtmlEntities.ts
Added decodeHtmlEntities(text: string): string that safely decodes HTML entities using DOMParser with input guards and fallbacks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibble labels, decode each name,
Parentheses hug values, not the same,
Digests find footing in OCI light,
Modals clearer in morning or night,
Hop on—confirmations now feel right!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: updating deletion statements (modal content and confirmation logic) across registry, package, and version levels using HTML entity decoding.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch AH-2866

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/ar/pages/version-details/components/VersionActions/DeleteVersionMenuItem.tsx (1)

28-45: ⚠️ Potential issue | 🟡 Minor

Avoid as any — use precise types for packageType and digest.

Two type-safety gaps here:

  1. Line 44: data?.packageType as any should be data?.packageType as RepositoryPackageType (which is already imported by useDeleteVersionModal). Using as any silently bypasses the enum constraint.
  2. Line 28 / VersionActionProps: digest?: any should be digest?: string to match the useDeleteVersionModal prop signature, preventing non-string values from slipping through at the call site.
🛠️ Proposed fix

In types.ts (VersionActionProps):

-  digest?: any
+  digest?: string

In DeleteVersionMenuItem.tsx:

-    packageType: data?.packageType as any,
+    packageType: data?.packageType as RepositoryPackageType,

RepositoryPackageType can be imported from @ar/common/types (already used in useDeleteVersionModal).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/src/ar/pages/version-details/components/VersionActions/DeleteVersionMenuItem.tsx`
around lines 28 - 45, Update the types and call-site to remove unsafe any casts:
change VersionActionProps.digest from digest?: any to digest?: string, and in
DeleteVersionMenuItem replace data?.packageType as any with data?.packageType
typed as RepositoryPackageType (import RepositoryPackageType from
`@ar/common/types` if needed) when calling useDeleteVersionModal; ensure
useDeleteVersionModal invocation matches its prop types (artifactKey, repoKey,
versionKey, artifactType, packageType: RepositoryPackageType, digest: string |
undefined) so the enum constraint and string-typed digest are enforced.
🧹 Nitpick comments (1)
web/src/ar/pages/repository-details/hooks/useDeleteRepositoryModal/useDeleteRepositoryModal.tsx (1)

26-31: Extract decodeHtmlEntities to a shared utility.

This function is copy-pasted verbatim in useDeleteArtifactModal.tsx and useDeleteVersionModal.tsx. It should live in a single shared location (e.g., @ar/utils/htmlUtils.ts) and be imported where needed.

♻️ Proposed refactor

Create web/src/ar/utils/htmlUtils.ts:

+/**
+ * Decodes HTML entities in a string using a temporary textarea element.
+ * Safe for browser environments only.
+ */
+export const decodeHtmlEntities = (text: string): string => {
+  const textarea = document.createElement('textarea')
+  textarea.innerHTML = text
+  return textarea.value
+}

Then in all three hook files, replace the local definition with:

-// Helper function to decode HTML entities
-const decodeHtmlEntities = (text: string): string => {
-  const textarea = document.createElement('textarea')
-  textarea.innerHTML = text
-  return textarea.value
-}
+import { decodeHtmlEntities } from '@ar/utils/htmlUtils'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/src/ar/pages/repository-details/hooks/useDeleteRepositoryModal/useDeleteRepositoryModal.tsx`
around lines 26 - 31, The local helper decodeHtmlEntities is duplicated across
useDeleteRepositoryModal, useDeleteArtifactModal, and useDeleteVersionModal;
extract it into a single shared utility (e.g., create and export
decodeHtmlEntities(text: string): string from a new module named htmlUtils.ts
under your AR utils), remove the local definitions in those three hooks, and
import the exported function (e.g., import { decodeHtmlEntities } from
'@ar/utils/htmlUtils') where needed, preserving the original TypeScript
signature and behavior so compilation and existing callers remain unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/ar/pages/version-details/hooks/useDeleteVersionModal.tsx`:
- Around line 58-62: The variable confirmationValue is inferred as string |
undefined because digest isn't narrowed through shouldUseDigest; change the
assignment to use an inline conditional that directly narrows digest (e.g. const
confirmationValue = isOCIPackage && digest ? digest : versionKey) so TypeScript
knows the truthy branch is string, then pass confirmationValue to
decodeHtmlEntities(confirmationValue); if you cannot guarantee a string, provide
a safe fallback or explicit non-null assertion where used.

---

Outside diff comments:
In
`@web/src/ar/pages/version-details/components/VersionActions/DeleteVersionMenuItem.tsx`:
- Around line 28-45: Update the types and call-site to remove unsafe any casts:
change VersionActionProps.digest from digest?: any to digest?: string, and in
DeleteVersionMenuItem replace data?.packageType as any with data?.packageType
typed as RepositoryPackageType (import RepositoryPackageType from
`@ar/common/types` if needed) when calling useDeleteVersionModal; ensure
useDeleteVersionModal invocation matches its prop types (artifactKey, repoKey,
versionKey, artifactType, packageType: RepositoryPackageType, digest: string |
undefined) so the enum constraint and string-typed digest are enforced.

---

Duplicate comments:
In
`@web/src/ar/pages/artifact-details/hooks/useDeleteArtifactModal/useDeleteArtifactModal.tsx`:
- Around line 27-32: The decodeHtmlEntities function is duplicated; remove the
local copy from useDeleteArtifactModal (the function named decodeHtmlEntities in
that file) and instead import a single shared implementation (create or use the
existing decodeHtmlEntities in the shared utilities module used by
useDeleteRepositoryModal) so both hooks reuse the same function; update the hook
to import decodeHtmlEntities from the shared util and delete the duplicated
local implementation.

In `@web/src/ar/pages/version-details/hooks/useDeleteVersionModal.tsx`:
- Around line 28-33: The file defines a duplicate helper function
decodeHtmlEntities (third occurrence); remove this local copy and replace its
uses with a single shared implementation: extract decodeHtmlEntities into a
common utility module (or use the existing shared helper if one already exists),
export it, then import and use that exported function in useDeleteVersionModal
(replace the local decodeHtmlEntities definition). Ensure the symbol name
decodeHtmlEntities is used consistently and delete the duplicate declaration
from this file.

---

Nitpick comments:
In
`@web/src/ar/pages/repository-details/hooks/useDeleteRepositoryModal/useDeleteRepositoryModal.tsx`:
- Around line 26-31: The local helper decodeHtmlEntities is duplicated across
useDeleteRepositoryModal, useDeleteArtifactModal, and useDeleteVersionModal;
extract it into a single shared utility (e.g., create and export
decodeHtmlEntities(text: string): string from a new module named htmlUtils.ts
under your AR utils), remove the local definitions in those three hooks, and
import the exported function (e.g., import { decodeHtmlEntities } from
'@ar/utils/htmlUtils') where needed, preserving the original TypeScript
signature and behavior so compilation and existing callers remain unchanged.

Comment on lines +58 to +62
const shouldUseDigest = isOCIPackage && digest
const confirmationValue = shouldUseDigest ? digest : versionKey

// Decode HTML entities to display properly
const decodedConfirmationValue = decodeHtmlEntities(confirmationValue)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n web/src/ar/pages/version-details/hooks/useDeleteVersionModal.tsx | head -100

Repository: abhinavcode/harness

Length of output: 4524


🏁 Script executed:

find . -name "tsconfig.json" -o -name "tsconfig*.json" | head -5

Repository: abhinavcode/harness

Length of output: 172


🏁 Script executed:

cat web/tsconfig.json

Repository: abhinavcode/harness

Length of output: 862


confirmationValue has type string | undefined — potential TypeScript error under strict mode.

TypeScript does not narrow digest through the intermediate shouldUseDigest variable. When shouldUseDigest ? digest : versionKey is evaluated, TS sees digest as string | undefined in the truthy branch, making confirmationValue: string | undefined. Passing it to decodeHtmlEntities(text: string) violates the type contract under strict mode.

Use an inline condition so TypeScript can narrow digest directly:

🛠️ Proposed fix
-  const shouldUseDigest = isOCIPackage && digest
-  const confirmationValue = shouldUseDigest ? digest : versionKey
+  const confirmationValue = (isOCIPackage && digest) ? digest : versionKey
📝 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
const shouldUseDigest = isOCIPackage && digest
const confirmationValue = shouldUseDigest ? digest : versionKey
// Decode HTML entities to display properly
const decodedConfirmationValue = decodeHtmlEntities(confirmationValue)
const confirmationValue = (isOCIPackage && digest) ? digest : versionKey
// Decode HTML entities to display properly
const decodedConfirmationValue = decodeHtmlEntities(confirmationValue)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/ar/pages/version-details/hooks/useDeleteVersionModal.tsx` around
lines 58 - 62, The variable confirmationValue is inferred as string | undefined
because digest isn't narrowed through shouldUseDigest; change the assignment to
use an inline conditional that directly narrows digest (e.g. const
confirmationValue = isOCIPackage && digest ? digest : versionKey) so TypeScript
knows the truthy branch is string, then pass confirmationValue to
decodeHtmlEntities(confirmationValue); if you cannot guarantee a string, provide
a safe fallback or explicit non-null assertion where used.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/ar/pages/version-details/hooks/useDeleteVersionModal.tsx (1)

58-67: ⚠️ Potential issue | 🟠 Major

Pass digest instead of versionKey to the delete API for OCI packages.

The confirmation UI correctly uses digest for OCI packages (Docker/Helm) at lines 52–56, but handleDeleteVersion (lines 58–67) always sends version: versionKey regardless of package type. The comment at line 46 indicates this was intended, but the implementation is incomplete. For OCI packages, the API call should pass the digest received in props to the mutation instead of versionKey.

Update the API call to:

const deleteParam = (isOCIPackage && digest) ? digest : versionKey
// Then use: version: deleteParam

This ensures the API receives the same value that the user confirmed in the modal.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/ar/pages/version-details/hooks/useDeleteVersionModal.tsx` around
lines 58 - 67, In useDeleteVersionModal's handleDeleteVersion, the delete API
always passes version: versionKey even for OCI packages; change it to compute a
deleteParam that uses digest when isOCIPackage and digest are present (e.g.
const deleteParam = (isOCIPackage && digest) ? digest : versionKey) and pass
version: deleteParam to the deleteVersion call so the mutation receives the same
value confirmed in the modal; update references to versionKey in
handleDeleteVersion accordingly.
🧹 Nitpick comments (1)
web/src/ar/common/utils/decodeHtmlEntities.ts (1)

39-39: Prefer doc.body.textContent over doc.documentElement.textContent.

doc.documentElement.textContent includes text from <head> (e.g. a decoded <title> element the parser hoisted out of body). doc.body.textContent is more targeted and avoids accidentally including head-level content.

♻️ Proposed refactor
-  return doc.documentElement.textContent || text
+  return doc.body?.textContent || text
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/ar/common/utils/decodeHtmlEntities.ts` at line 39, The function
decodeHtmlEntities currently returns doc.documentElement.textContent which can
include head-level text; change it to prefer doc.body.textContent (falling back
to doc.documentElement.textContent or the original input `text` if body is null)
so decoding only pulls visible body content; update the return in
decodeHtmlEntities to use doc.body.textContent ||
doc.documentElement.textContent || text and keep the rest of the function
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/ar/common/utils/decodeHtmlEntities.ts`:
- Around line 25-27: Update the JSDoc for decodeHtmlEntities to correct the
second example and clarify behavior: change the example input
'&lt;script&gt;alert(1)&lt;/script&gt;' to show that the function returns the
script element's textContent (e.g. 'alert(1)') rather than the literal
'<script>...</script>', and add a brief note that any decoded input that forms
real HTML elements will have tags stripped because the function uses
DOMParser/documentElement.textContent; reference the decodeHtmlEntities function
name so the comment sits next to the implementation.

---

Outside diff comments:
In `@web/src/ar/pages/version-details/hooks/useDeleteVersionModal.tsx`:
- Around line 58-67: In useDeleteVersionModal's handleDeleteVersion, the delete
API always passes version: versionKey even for OCI packages; change it to
compute a deleteParam that uses digest when isOCIPackage and digest are present
(e.g. const deleteParam = (isOCIPackage && digest) ? digest : versionKey) and
pass version: deleteParam to the deleteVersion call so the mutation receives the
same value confirmed in the modal; update references to versionKey in
handleDeleteVersion accordingly.

---

Duplicate comments:
In `@web/src/ar/pages/version-details/hooks/useDeleteVersionModal.tsx`:
- Around line 52-56: confirmationValue is inferred as string | undefined because
digest isn't narrowed via shouldUseDigest, so pass a guaranteed string to
decodeHtmlEntities: replace the two-step logic (shouldUseDigest +
confirmationValue) with a single inline conditional that directly narrows digest
(e.g., set confirmationValue using isOCIPackage && digest ? digest : versionKey)
so decodeHtmlEntities receives a string; reference: shouldUseDigest,
confirmationValue, decodeHtmlEntities, digest, versionKey.

---

Nitpick comments:
In `@web/src/ar/common/utils/decodeHtmlEntities.ts`:
- Line 39: The function decodeHtmlEntities currently returns
doc.documentElement.textContent which can include head-level text; change it to
prefer doc.body.textContent (falling back to doc.documentElement.textContent or
the original input `text` if body is null) so decoding only pulls visible body
content; update the return in decodeHtmlEntities to use doc.body.textContent ||
doc.documentElement.textContent || text and keep the rest of the function
unchanged.

Comment on lines +25 to +27
* decodeHtmlEntities('github.com&#x2F;rs&#x2F;xid') // returns 'github.com/rs/xid'
* decodeHtmlEntities('&lt;script&gt;alert(1)&lt;/script&gt;') // returns '<script>alert(1)</script>' (safe, no execution)
*/

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

JSDoc second example has an incorrect return value.

When '&lt;script&gt;alert(1)&lt;/script&gt;' is passed to DOMParser.parseFromString, the HTML tokenizer decodes the entities first, producing <script>alert(1)</script>, which the parser materialises as an actual <script> DOM element. doc.documentElement.textContent then returns 'alert(1)' — the text content of the script node — not '<script>alert(1)</script>' as the comment claims.

The security note ("safe, no execution") is correct, but the stated return value is misleading. More broadly, any decoded string that forms valid HTML elements (e.g. &lt;b&gt;text&lt;/b&gt;) would have the tag markup stripped from the result, which could cause a display mismatch if package keys ever contain <, > encoded as HTML entities.

📝 Corrected JSDoc example
- * decodeHtmlEntities('&lt;script&gt;alert(1)&lt;/script&gt;') // returns '<script>alert(1)</script>' (safe, no execution)
+ * decodeHtmlEntities('&lt;script&gt;alert(1)&lt;/script&gt;') // returns 'alert(1)' (HTML tags stripped; safe, no execution)
📝 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
* decodeHtmlEntities('github.com&#x2F;rs&#x2F;xid') // returns 'github.com/rs/xid'
* decodeHtmlEntities('&lt;script&gt;alert(1)&lt;/script&gt;') // returns '<script>alert(1)</script>' (safe, no execution)
*/
* decodeHtmlEntities('github.com&#x2F;rs&#x2F;xid') // returns 'github.com/rs/xid'
* decodeHtmlEntities('&lt;script&gt;alert(1)&lt;/script&gt;') // returns 'alert(1)' (HTML tags stripped; safe, no execution)
*/
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/ar/common/utils/decodeHtmlEntities.ts` around lines 25 - 27, Update
the JSDoc for decodeHtmlEntities to correct the second example and clarify
behavior: change the example input '&lt;script&gt;alert(1)&lt;/script&gt;' to
show that the function returns the script element's textContent (e.g.
'alert(1)') rather than the literal '<script>...</script>', and add a brief note
that any decoded input that forms real HTML elements will have tags stripped
because the function uses DOMParser/documentElement.textContent; reference the
decodeHtmlEntities function name so the comment sits next to the implementation.

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