Skip to content

fix(admin-ui): Use typescript generated SCRIPTS pages#2478

Merged
duttarnab merged 26 commits intomainfrom
admin-ui-2464
Dec 4, 2025
Merged

fix(admin-ui): Use typescript generated SCRIPTS pages#2478
duttarnab merged 26 commits intomainfrom
admin-ui-2464

Conversation

@syntrydy
Copy link
Contributor

@syntrydy syntrydy commented Nov 26, 2025

#2464
Closes #2464

Summary by CodeRabbit

  • New Features

    • Full Custom Scripts UI: list/filter/search/sort/paginate/add/edit/view/delete with detail panel, person-authentication fields, mutation-driven flows, toasts, audit/webhook logging.
  • Bug Fixes

    • Improved form validation, clearer loading/submission indicators, conditional spacing fixes, and more reliable sidebar/submenu animations.
  • Documentation

    • Added/expanded EN/ES/FR/PT localization strings for script management and UI labels.
  • Refactor

    • Modernized animation and hooks to TypeScript classes, stronger typings, consolidated hooks/api surface, and theme entries now include borderColor.

✏️ Tip: You can customize this high-level summary in your review settings.

@syntrydy syntrydy self-assigned this Nov 26, 2025
@syntrydy syntrydy requested a review from duttarnab as a code owner November 26, 2025 22:40
@syntrydy syntrydy added comp-admin-ui Component affected by issue or PR comp-docker-admin-ui Component affected by issue or PR labels Nov 26, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 26, 2025

Warning

Rate limit exceeded

@syntrydy has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 5 minutes and 35 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 9a32e1a and 1a9770a.

📒 Files selected for processing (1)
  • admin-ui/app/routes/Apps/Gluu/GluuProperties.tsx (3 hunks)
📝 Walkthrough

Walkthrough

Replaces legacy sidebar animation modules with typed TypeScript classes; migrates Custom Scripts UI from Redux/sagas to React Query hooks/mutations with webhooks and audit logging; adds new Custom Scripts components, hooks, types, constants, translations, and several small tightening/refactor edits.

Changes

Cohort / File(s) Summary
Animation modules → TS classes
\admin-ui/app/components/dashboard-style-airframe/side-menu-animate.ts`, `admin-ui/app/components/dashboard-style-airframe/sidebar-entry-animate.ts`, `admin-ui/app/components/dashboard-style-airframe/slim-menu-animate.ts`, `admin-ui/app/components/dashboard-style-airframe/slim-sidebar-animate.ts``
Converted function-style modules to default-exported TypeScript classes with typed fields, constructors, lifecycle methods (assign/destroy), MutationObserver handling, animejs typings, and stronger DOM/type guards.
Sidebar integration
\admin-ui/app/components/Sidebar/SidebarContent.tsx`, `admin-ui/app/components/dashboard-style-airframe/index.ts``
Switched dynamic requires to ES imports, added typed nullable animation instance fields, moved instantiation to componentDidMount, used optional chaining on destroy, and removed top-level ts-nocheck.
CustomScripts hooks & API
\admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts`, `admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptActions.ts`, `admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts`, `admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts`, `admin-ui/plugins/admin/components/CustomScripts/hooks/index.ts``
Added React Query fetch/mutation hooks (list, by-type, single), create/update/delete mutations that invalidate queries, trigger webhooks and audit logs, plus aggregated hook exports and a useMutationEffects hook for toast/navigation side-effects.
CustomScripts UI & pages
\admin-ui/plugins/admin/components/CustomScripts/CustomScriptAddPage.tsx`, `admin-ui/plugins/admin/components/CustomScripts/CustomScriptEditPage.tsx`, `admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx`, `admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx`, `admin-ui/plugins/admin/components/CustomScripts/CustomScriptDetailPage.tsx`, `admin-ui/plugins/admin/components/CustomScripts/PersonAuthenticationFields.tsx`, `admin-ui/plugins/admin/components/CustomScripts/ScriptListPage.tsx``
New/updated React components wired to the new hooks: mutation-driven submits, Formik adjustments, centralized person-auth fields component, and a list page with filtering/pagination/detail panel.
CustomScripts constants & utils
\admin-ui/plugins/admin/components/CustomScripts/constants.ts`, `admin-ui/plugins/admin/components/CustomScripts/helper/utils.ts`, `admin-ui/plugins/admin/components/CustomScripts/types/forms.ts``
Introduced DEFAULT_SCRIPT_TYPE, SCRIPT_CACHE_CONFIG, SAML_ACRS_OPTIONS, PROGRAMMING_LANGUAGES, LOCATION_TYPE_OPTIONS; widened/hardened utils signatures and defaults (transformToFormValues, getModuleProperty); updated form types.
CustomScripts types & state cleanup
\admin-ui/plugins/admin/components/CustomScripts/types/actions.ts`, `admin-ui/plugins/admin/components/CustomScripts/types/index.ts`, `admin-ui/plugins/admin/components/CustomScripts/types/state.ts`, `admin-ui/plugins/admin/components/CustomScripts/types/customScript.ts``
Removed legacy Redux state/type exports, pruned obsolete interfaces, and adjusted several public type signatures (union item types, async submit).
Plugin metadata & routing
\admin-ui/plugins/scripts/plugin-metadata.ts`, `admin-ui/plugins/PluginMenuResolver.js``
Switched route to CustomScriptListPage, removed script reducer/saga from plugin metadata, and tightened local variable declarations to const.
Localization
\admin-ui/app/locales/en/translation.json`, `admin-ui/app/locales/es/translation.json`, `admin-ui/app/locales/fr/translation.json`, `admin-ui/app/locales/pt/translation.json``
Added numerous script-related and UI localization keys (retry, search, script_* messages, placeholders, tooltips, options); ES locale also removes a legacy retry key in a different block.
Auth-server & UI tweaks
\admin-ui/plugins/auth-server/components/AuthN/AuthNListPage.js`, `admin-ui/app/routes/Apps/Gluu/GluuPropertyItem.tsx`, `admin-ui/app/routes/Apps/Gluu/GluuProperties.tsx``
Replaced Redux selection with useCustomScriptsByType(DEFAULT_SCRIPT_TYPE), adjusted placeholder selection/spacing, and centralized Formik property sync logic.
Audit & mutation effects
\admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts`, `admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts``
New audit logging helper that builds/posts AuditLog; useMutationEffects dispatches success/error toasts and optionally navigates on mutation lifecycle events.
Misc tightening & small edits
many files (examples: \admin-ui/app/redux/api/LicenseApi.ts`, `admin-ui/plugins/services/redux/api/LdapApi.js`, `admin-ui/plugins/admin/redux/features/{apiRoleSlice.js,mappingSlice.js}`, `admin-ui/plugins/admin/components/Webhook/WebhookURLChecker.js`, `admin-ui/plugins/services/Components/Configuration/LdapAddPage.js``)
Numerous local variable declarations tightened to const, minor JSX/fragment cleanups, and small non-functional refactors.
Types & tooling
\admin-ui/app/utils/TokenController.ts`, `admin-ui/package.json``
Exported AdditionalPayload type and added @types/animejs devDependency for animejs typings.
Theme config
\admin-ui/app/context/theme/config.ts``
Added borderColor property to each theme entry set to customColors.lightGray.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant UI as Custom Scripts UI
    participant Hooks as useCustomScriptApi
    participant Cache as React Query Cache
    participant API as Backend API
    participant Webhook as WebhookService
    participant Audit as AuditService

    U->>UI: Open list / interact (search/filter)
    UI->>Hooks: useCustomScriptsByType(type)
    Hooks->>Cache: check cache key
    alt cache miss
        Hooks->>API: GET /scripts?type=...
        API-->>Hooks: 200 scripts
        Hooks->>Cache: store response
    else cache hit
        Cache-->>Hooks: cached data
    end
    Hooks-->>UI: data + loading

    U->>UI: create/update/delete script
    UI->>Hooks: mutateAsync(payload)
    Hooks->>API: POST/PUT/DELETE /scripts
    API-->>Hooks: success/error
    Hooks->>Cache: invalidate related queries
    Hooks->>Webhook: trigger webhook (if configured)
    Hooks->>Audit: post audit log
    Hooks-->>UI: mutation result
    UI->>U: toast / optional navigate (useMutationEffects)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Focus review areas:
    • admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts — query keys, invalidation, webhook and audit side-effects.
    • admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx & PersonAuthenticationFields.tsx — Formik wiring, moduleProperties mapping, edit-mode guards.
    • admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx — pagination, filtering, permission gating, delete flow and detail panel.
    • admin-ui/app/components/dashboard-style-airframe/* — animejs typings, timeline lifecycle, MutationObserver correctness.

Possibly related PRs

Suggested reviewers

  • duttarnab
  • moabu
  • faisalsiddique4400

Poem

🐇 I hopped through hooks and animated seams,

Classes chased out old function dreams.
Webhooks chimed and audit logs took note,
New locales bloomed and themes got a coat.
I thumped my paw — the admin UI beams.

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR achieves the primary objectives from #2464: replaces manually created types with TypeScript-generated types, removes Redux implementations (api, features, saga), and converts animation/form components to TypeScript classes. However, there are unresolved bug reports about custom properties display and disabled Apply button. Address the reported issues: investigate why custom properties don't display for some scripts and why the Apply button remains disabled on the Add Script page. These are blocker issues that prevent the feature from working correctly.
Out of Scope Changes check ⚠️ Warning The PR includes significant out-of-scope refactoring: animation components converted from functions to TypeScript classes (SideMenuAnimate, SidebarEntryAnimate, SlimMenuAnimate, SlimSidebarAnimate), localization updates, Redux utility variable changes (let to const), and type system extensions. These changes exceed the stated objective of replacing types and removing Redux. Separate the animation component refactoring and other utility changes into a dedicated PR. Keep this PR focused solely on: replacing manual types with TypeScript-generated types, removing Redux folder contents, and updating the custom scripts pages to use the new types.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ 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 'fix(admin-ui): Use typescript generated SCRIPTS pages' accurately describes the main objective of the PR: migrating from manually created types to TypeScript-generated types for custom scripts pages.

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.

@mo-auto mo-auto added the kind-bug Issue or PR is a bug in existing functionality label Nov 26, 2025
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: 24

Caution

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

⚠️ Outside diff range comments (6)
admin-ui/plugins/admin/components/Webhook/WebhookURLChecker.js (1)

24-33: Prefer for...of or array methods over for...in for arrays.

The change from let to const is fine. However, for...in iterates over array indices (keys), not values, which is error-prone and non-idiomatic for arrays. Consider refactoring to use Array.prototype.some() for clarity and conciseness.

 const isAllowed = (url) => {
-  let result = true
-  for (const extention in NOT_ALLOWED) {
-    if (url.startsWith(NOT_ALLOWED[extention])) {
-      result = false
-      break
-    }
-  }
-  return result
+  return !NOT_ALLOWED.some((prefix) => url.startsWith(prefix))
 }
admin-ui/plugins/admin/redux/features/mappingSlice.js (1)

44-54: Add boundary check and simplify Redux Toolkit mutation pattern.

Two issues:

  1. Missing boundary check: findIndex returns -1 if the role is not found. Lines 48-49 will attempt to access and mutate state.items[-1].permissions, causing undefined behavior or runtime errors.

  2. Redundant alias-mutate-spread pattern: With Redux Toolkit's Immer, you can directly remove the permission using splice on state.items[index].permissions. The current alias pattern is unnecessarily complex.

Apply this diff:

 updateMapping: (state, action) => {
   if (action.payload?.data) {
     const { id, role } = action.payload.data
     const index = state.items.findIndex((element) => element.role === role)
+    if (index === -1) return
-    const permissions = state.items[index].permissions
-    permissions.splice(id, 1)
-    const changedPermissions = state.items
-    changedPermissions[index].permissions = permissions
-    state.items = [...changedPermissions]
+    state.items[index].permissions.splice(id, 1)
   }
 },
admin-ui/plugins/services/redux/api/LdapApi.js (1)

50-58: Minor readability tweak for testLdapConfig options construction

You can simplify the options creation while keeping behavior identical:

-  testLdapConfig = (input) => {
-    const options = {}
-    options['gluuLdapConfiguration'] = input
+  testLdapConfig = (input) => {
+    const options = {
+      gluuLdapConfiguration: input,
+    }

This avoids the intermediate empty object + mutation and makes the payload shape clearer at a glance.

admin-ui/app/components/dashboard-style-airframe/side-menu-animate.ts (1)

77-86: Duplicate destroy method definition

SideMenuAnimate.prototype.destroy is defined twice with identical bodies. While this doesn’t change behavior (the second overrides the first with the same implementation), it’s redundant and slightly confusing.

Consider removing one of the duplicate definitions to reduce noise:

-SideMenuAnimate.prototype.destroy = function () {
-  this._nodesObserver.disconnect()
-}
-
 /**
  * Disconnects the observer
  */
 SideMenuAnimate.prototype.destroy = function () {
   this._nodesObserver.disconnect()
 }
admin-ui/app/components/dashboard-style-airframe/slim-menu-animate.ts (1)

46-83: Unreachable mouse‑out animation code

Inside mouseOutHandler, there is an unconditional return before the timeline is constructed:

this.mouseOutHandler = function () {
  if (_this._animationsEnabled()) {
    const triggerElement = this
    const subMenuElement = triggerElement.querySelector(':scope > .sidebar-submenu')
    return
    const timeline = anime.timeline({ /* ... */ })
    // ...
  }
}

As written, the mouse‑out animation never runs, and everything after return is dead code. If the intent is to have no mouse‑out animation, consider deleting the unused block; if you do want the closing animation, drop the return (and re‑verify styles).

-    const subMenuElement = triggerElement.querySelector(':scope > .sidebar-submenu')
-    return
-    const timeline = anime
+    const subMenuElement = triggerElement.querySelector(':scope > .sidebar-submenu')
+    const timeline = anime
       .timeline({
         targets: subMenuElement,
         duration: ANIMATION_DURATION,
         // ...
       })
admin-ui/plugins/auth-server/components/AuthN/AuthNListPage.js (1)

117-130: Stale closure risk: scriptsLoading and list not in dependency array.

The effect references scriptsLoading and list but only depends on [scripts]. This can cause stale values. Use functional state update to avoid needing list in deps:

   useEffect(() => {
-    setList({ ...list, scripts: [] })
     if (scripts.length > 0 && !scriptsLoading) {
       const getEnabledscripts = scripts.filter((item) => item.enabled === true)
       if (getEnabledscripts?.length > 0) {
         const updateScriptsItems = getEnabledscripts.map((item) => ({
           ...item,
           name: 'myAuthnScript',
           acrName: item.name,
         }))
-        setList({ ...list, scripts: updateScriptsItems })
+        setList((prev) => ({ ...prev, scripts: updateScriptsItems }))
+      } else {
+        setList((prev) => ({ ...prev, scripts: [] }))
       }
+    } else {
+      setList((prev) => ({ ...prev, scripts: [] }))
     }
-  }, [scripts])
+  }, [scripts, scriptsLoading])
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32270a4 and 57db7f5.

📒 Files selected for processing (32)
  • admin-ui/app/components/dashboard-style-airframe/side-menu-animate.ts (3 hunks)
  • admin-ui/app/components/dashboard-style-airframe/sidebar-entry-animate.ts (5 hunks)
  • admin-ui/app/components/dashboard-style-airframe/slim-menu-animate.ts (4 hunks)
  • admin-ui/app/components/dashboard-style-airframe/slim-sidebar-animate.ts (2 hunks)
  • admin-ui/app/locales/en/translation.json (7 hunks)
  • admin-ui/app/locales/es/translation.json (7 hunks)
  • admin-ui/app/locales/fr/translation.json (7 hunks)
  • admin-ui/app/locales/pt/translation.json (7 hunks)
  • admin-ui/app/redux/api/LicenseApi.ts (2 hunks)
  • admin-ui/app/routes/Apps/Gluu/GluuPropertyItem.tsx (1 hunks)
  • admin-ui/plugins/PluginMenuResolver.js (2 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptAddPage.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptEditPage.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx (10 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/PersonAuthenticationFields.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/ScriptListPage.tsx (0 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/ScriptListPage.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/constants.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/helper/utils.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/index.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptActions.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (1 hunks)
  • admin-ui/plugins/admin/components/Webhook/WebhookURLChecker.js (1 hunks)
  • admin-ui/plugins/admin/redux/features/apiRoleSlice.js (1 hunks)
  • admin-ui/plugins/admin/redux/features/mappingSlice.js (2 hunks)
  • admin-ui/plugins/auth-server/components/AuthN/AuthNListPage.js (2 hunks)
  • admin-ui/plugins/scripts/plugin-metadata.ts (3 hunks)
  • admin-ui/plugins/services/Components/Configuration/LdapAddPage.js (1 hunks)
  • admin-ui/plugins/services/redux/api/LdapApi.js (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts
🧬 Code graph analysis (9)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (11)
admin-ui/plugins/auth-server/components/AuthN/AuthNListPage.js (3)
  • useTranslation (25-25)
  • dispatch (26-26)
  • theme (30-30)
admin-ui/plugins/services/Components/Configuration/LdapAddPage.js (1)
  • dispatch (10-10)
admin-ui/app/utils/pagingUtils.ts (1)
  • getPagingSize (1-24)
admin-ui/plugins/admin/components/CustomScripts/constants.ts (1)
  • DEFAULT_SCRIPT_TYPE (1-1)
admin-ui/plugins/user-management/types/CommonTypes.ts (1)
  • ThemeContext (13-17)
admin-ui/plugins/admin/components/CustomScripts/hooks/index.ts (3)
  • useCustomScriptsByType (3-3)
  • useCustomScriptTypes (8-8)
  • useDeleteCustomScript (7-7)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (3)
  • useCustomScriptsByType (68-84)
  • useCustomScriptTypes (190-225)
  • useDeleteCustomScript (155-188)
admin-ui/plugins/admin/redux/sagas/ApiPermissionSaga.js (1)
  • errorMessage (100-100)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
admin-ui/plugins/services/Components/Configuration/LdapListPage.js (1)
  • tableOptions (251-257)
admin-ui/app/components/Sidebar/types.ts (1)
  • MenuItem (2-10)
admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (2)
admin-ui/plugins/admin/redux/features/types/customScript.ts (1)
  • CustomScriptItem (29-46)
admin-ui/plugins/admin/components/CustomScripts/types/customScript.ts (1)
  • CustomScriptItem (29-49)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptEditPage.tsx (3)
admin-ui/app/helpers/navigation.ts (2)
  • useAppNavigation (66-95)
  • ROUTES (97-97)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (2)
  • useCustomScript (86-95)
  • useUpdateCustomScript (123-153)
admin-ui/plugins/admin/components/CustomScripts/types/actions.ts (1)
  • SubmitData (11-14)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx (5)
admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (1)
  • CustomScriptFormProps (6-11)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1)
  • useCustomScriptTypes (190-225)
admin-ui/plugins/admin/components/CustomScripts/PersonAuthenticationFields.tsx (1)
  • PersonAuthenticationFields (18-82)
admin-ui/plugins/admin/components/CustomScripts/helper/utils.ts (1)
  • getModuleProperty (6-13)
admin-ui/plugins/admin/components/CustomScripts/constants.ts (2)
  • PROGRAMMING_LANGUAGES (17-20)
  • LOCATION_TYPE_OPTIONS (22-25)
admin-ui/plugins/admin/components/CustomScripts/helper/utils.ts (2)
admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (1)
  • FormValues (17-32)
admin-ui/app/utils/Util.ts (1)
  • filterEmptyObjects (82-84)
admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts (2)
admin-ui/app/utils/TokenController.ts (1)
  • addAdditionalData (49-124)
admin-ui/app/redux/api/backend-api.ts (1)
  • postUserAction (51-69)
admin-ui/plugins/auth-server/components/AuthN/AuthNListPage.js (2)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1)
  • useCustomScriptsByType (68-84)
admin-ui/plugins/admin/components/CustomScripts/constants.ts (1)
  • DEFAULT_SCRIPT_TYPE (1-1)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (3)
admin-ui/plugins/admin/redux/sagas/WebhookSaga.ts (1)
  • triggerWebhook (279-368)
admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts (1)
  • logAuditAction (41-60)
admin-ui/plugins/admin/components/CustomScripts/constants.ts (1)
  • SCRIPT_CACHE_CONFIG (3-9)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptAddPage.tsx (2)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1)
  • useCreateCustomScript (97-121)
admin-ui/plugins/admin/components/CustomScripts/types/actions.ts (1)
  • SubmitData (11-14)
🪛 Biome (2.1.2)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptActions.ts

[error] 30-30: This hook is being called from a nested function, but all hooks must be called unconditionally from the top-level component.

For React to preserve state between calls, hooks needs to be called unconditionally and always in the same order.
See https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level

(lint/correctness/useHookAtTopLevel)


[error] 37-37: This hook is being called from a nested function, but all hooks must be called unconditionally from the top-level component.

For React to preserve state between calls, hooks needs to be called unconditionally and always in the same order.
See https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level

(lint/correctness/useHookAtTopLevel)


[error] 41-41: This hook is being called from a nested function, but all hooks must be called unconditionally from the top-level component.

For React to preserve state between calls, hooks needs to be called unconditionally and always in the same order.
See https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level

(lint/correctness/useHookAtTopLevel)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (49)
admin-ui/plugins/PluginMenuResolver.js (1)

39-39: Use of const for pluginRoutes is correct and idiomatic

Both processRoutes and processRoutesSync only mutate pluginRoutes via .push and never reassign the variable, so switching from let to const is safe and clarifies intent without changing behavior.

Also applies to: 85-85

admin-ui/app/locales/en/translation.json (7)

51-51: ✓ Approved: New "retry" action added.

Clear, concise localization entry supporting retry functionality for async operations.

Also applies to: 51-51


103-103: ✓ Approved: New "search" field added to dashboard/fields.

Supports search UI component in dashboard context, consistent with field naming conventions.

Also applies to: 103-103


416-419: ✓ Approved: New pagination and SAML ACR field labels added.

Lines 416-419 add well-organized localization keys:

  • saml_acrs: Aligns with existing SAML field naming
  • rows_per_page, of, more_than: Standard pagination/display text

Terminology is appropriate for table UI controls.


823-834: ✓ Approved: Script management CRUD operation messages added.

Comprehensive set of 12 localization keys (lines 823–834) covering script lifecycle:

  • Success messages: script_added_successfully, script_deleted_successfully, script_updated_successfully
  • Error messages: error_adding_script, error_deleting_script, error_updating_script
  • Status/state messages: loading_script, error_loading_script, error_loading_scripts, script_not_found, no_scripts_found

Terminology is consistent with existing message patterns (e.g., invalid_script_data). All keys support the PR's migration to React Query–based script management.


875-875: ✓ Approved: Tooltip for sort order toggling added.

Clear, instructive tooltip for ascending/descending sort functionality. Placement in tooltips section is appropriate.

Also applies to: 875-875


926-926: ✓ Approved: Script search placeholder added.

Placeholder text "Search scripts by name or description" is user-friendly and follows existing placeholder conventions (e.g., line 925 search_pattern).

Also applies to: 926-926


1069-1069: ✓ Approved: Storage location type options added.

Lines 1069 and 1075 add database and file options, supporting script storage location selection. Placement in options section and terminology are consistent with existing patterns.

Also applies to: 1075-1075

admin-ui/app/locales/es/translation.json (7)

51-51: ✓ Approved: Spanish translation for "retry" action.

Translation "Reintentar" is appropriate and idiomatic for Spanish-speaking users.

Also applies to: 51-51


103-103: ✓ Approved: Spanish translation for "search" field.

Translation "Buscar" aligns with existing Spanish field translations (e.g., line 36 search: "Buscar").

Also applies to: 103-103


416-419: ✓ Approved: Spanish translations for pagination and SAML fields.

Translations are consistent with existing Spanish terminology:

  • saml_acrs: "SAML ACRS" (parallels English)
  • rows_per_page: "Filas por página" (standard Spanish for table pagination)
  • of: "de" (preposition used in Spanish pagination e.g., "1 de 10")
  • more_than: "más de" (comparative form in Spanish)

All translations follow existing conventions observed in the file.


822-833: ✓ Approved: Spanish translations for script management messages.

All 12 script operation messages are appropriately translated:

  • Success messages use "exitosamente" (successfully)
  • Error messages use "Error al" (Error... / Error when...) pattern consistent with line 816–821
  • Loading states: "Cargando script..." aligns with existing loading patterns (e.g., line 837 fetching_project_details)
  • Status messages follow natural Spanish phrasing

Terminology mirrors English structure for consistency across UI.


871-871: ✓ Approved: Spanish tooltip for sort order toggling.

Translation "Alternar orden (ascendente/descendente)" clearly conveys toggle functionality and is consistent with existing Spanish tooltip style.

Also applies to: 871-871


919-919: ✓ Approved: Spanish placeholder for script search.

Placeholder "Buscar scripts por nombre o descripción" is idiomatic, user-friendly, and matches the structure of the English version (line 926).

Also applies to: 919-919


1062-1062: ✓ Approved: Spanish translations for storage location options.

  • database: "Base de datos" (standard Spanish term for database)
  • file: "Archivo" (standard Spanish term for file)

Both translations are concise and consistent with existing Spanish option terminology in the file.

Also applies to: 1068-1068

admin-ui/app/locales/fr/translation.json (1)

168-168: Translation keys properly added and appropriately localized for French.

All new script-management-related keys have been added consistently across the French translation file with contextually appropriate French translations. The messages maintain clarity and follow established patterns in the codebase (e.g., script operation status messages like script_added_successfully, error_adding_script). JSON structure is valid with no duplicates.

Also applies to: 179-179, 531-534, 759-770, 812-812, 860-860

admin-ui/app/locales/pt/translation.json (1)

165-165: Translation keys properly added and appropriately localized for Portuguese.

All new script-management-related keys have been added consistently across the Portuguese translation file, mirroring the French file additions with contextually appropriate Portuguese translations. The terminology remains consistent with the French translations where applicable (e.g., untranslated "script" terms). JSON structure is valid with no duplicates.

Also applies to: 176-176, 544-547, 754-765, 807-807, 853-853

admin-ui/app/routes/Apps/Gluu/GluuPropertyItem.tsx (1)

77-77: LGTM! Conditional margin improves alignment.

The change correctly applies top margin only when input labels are present, ensuring proper vertical alignment of the remove button with labeled input fields. When labels are absent, the unnecessary margin is removed, maintaining consistent spacing.

Note: This UI alignment fix appears unrelated to the main PR objective of migrating SCRIPTS pages from Redux to React Query with TypeScript-generated types.

admin-ui/app/redux/api/LicenseApi.ts (1)

33-33: LGTM! Correct immutability improvement.

Changing retries from let to const is correct—the outer variable is only read once to initialize the recursive call and never reassigned. The parameter in makeRequest shadows this variable and handles the incrementing.

Also applies to: 64-64

admin-ui/plugins/services/Components/Configuration/LdapAddPage.js (1)

25-31: Const binding for message is safe and clarifies intent

message is never reassigned, so switching to const is correct and keeps the function behavior unchanged.

admin-ui/plugins/services/redux/api/LdapApi.js (1)

18-27: Immutability cleanup in updateLdapConfig / addLdapConfig looks good

Using const options here is appropriate since the binding is never reassigned and the behavior of both methods is preserved.

Also applies to: 30-39

admin-ui/app/components/dashboard-style-airframe/side-menu-animate.ts (1)

3-52: anime import and local const/let usage are correct

The switch to const for the anime import, option, and other locals plus let for activeAnimation preserves the existing animation behavior while tightening scoping. No functional regressions stand out.

admin-ui/app/components/dashboard-style-airframe/slim-sidebar-animate.ts (1)

2-267: Let/const refactor maintains sidebar animation behavior

The refactor to use const for config and DOM/query results and let for timelineStage1, timelineStage2, and isAnimating is consistent and preserves the existing two‑stage animation logic. No new scoping or hoisting issues are introduced.

admin-ui/app/components/dashboard-style-airframe/sidebar-entry-animate.ts (1)

3-97: executeAnimation refactor to const/let is safe

Using const for config, sidebarElement, the section arrays, and timeline, plus let for sidebarMenuSection and sideMenuEntries, keeps the original animation flow and side effects while improving scoping. No functional differences are introduced.

admin-ui/app/components/dashboard-style-airframe/slim-menu-animate.ts (1)

3-44: Const/let usage and animation constants look good

Using const for anime, the ANIMATION_* constants, _this captures, and timeline/element references appropriately narrows mutability while keeping the hover‑in animation behavior unchanged.

Also applies to: 87-123

admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts (1)

6-26: LGTM!

Good defensive coding with proper null checks for required authentication data before constructing the audit log.

admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (2)

7-8: Type inconsistency: item accepts CustomScript but handleSubmit only accepts CustomScriptItem.

The item prop now accepts CustomScript | CustomScriptItem, but handleSubmit data parameter still only accepts { customScript: CustomScriptItem }. If a CustomScript is passed as item and submitted, the types would be inconsistent.

Consider whether handleSubmit should also accept CustomScript:

-  handleSubmit: (data: { customScript: CustomScriptItem }) => void | Promise<void>
+  handleSubmit: (data: { customScript: CustomScriptItem | CustomScript }) => void | Promise<void>

Or verify that form transformation always produces CustomScriptItem regardless of input type.


10-14: LGTM!

The isSubmitting prop and broadened row type align well with the async mutation flow introduced in the edit/add pages.

admin-ui/plugins/auth-server/components/AuthN/AuthNListPage.js (1)

44-48: LGTM!

The migration from Redux selectors to useCustomScriptsByType hook is implemented correctly. The optional chaining on scriptsResponse?.entries properly handles the loading state.

admin-ui/plugins/admin/components/CustomScripts/CustomScriptEditPage.tsx (4)

28-55: LGTM!

The mounted flag pattern provides reasonable protection against dispatching actions after component unmount, especially for navigation. The separation of success and error effects is clean.


57-75: LGTM!

The submission flow correctly validates input, extracts the action message for audit logging, and delegates error display to the mutation state effect.


77-106: LGTM!

Comprehensive loading and error state handling with appropriate fallback messages.


108-121: LGTM!

The form is correctly wired with the mutation pending state for both the loader and the isSubmitting prop.

admin-ui/plugins/admin/components/CustomScripts/CustomScriptAddPage.tsx (2)

50-68: LGTM!

The submission flow correctly validates, extracts the action message, and calls the mutation.


74-78: LGTM!

Passing an empty object for the add flow is appropriate, assuming CustomScriptForm handles default values internally.

admin-ui/plugins/admin/components/CustomScripts/constants.ts (1)

1-25: LGTM!

Constants are well-organized with sensible cache timing values. The separation of configuration, options arrays, and localization keys follows good practices for maintainability.

admin-ui/plugins/scripts/plugin-metadata.ts (2)

2-2: LGTM!

Import updated correctly to reference the new CustomScriptListPage component, aligning with the migration from Redux to React Query.


39-40: Clean Redux removal.

Emptying the reducers and sagas arrays completes the migration away from Redux for script management while maintaining the plugin metadata interface.

admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx (4)

50-52: LGTM!

The isEditMode derivation and useCustomScriptTypes hook integration are clean. Preventing script type modification in edit mode is the correct business logic.


292-310: LGTM!

The MUI Alert component with error styling and action button is well-implemented. The conditional rendering based on scriptError?.stackTrace provides clear error visibility.


360-365: Good component extraction.

Extracting PersonAuthenticationFields reduces form complexity and improves maintainability. Props are correctly passed including the getModuleProperty helper.


426-431: LGTM!

Using centralized PROGRAMMING_LANGUAGES constant instead of inline options improves maintainability and consistency.

admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (5)

50-52: LGTM!

The ScriptTableRow interface extending CustomScript with an index signature is necessary for MaterialTable's dynamic property access.


150-169: LGTM!

The delete confirmation handler properly uses mutateAsync with try-catch, shows appropriate toast messages, and cleans up state on success. Error message extraction handles both Error instances and fallback translation.


311-374: LGTM!

Actions are correctly gated by permission checks (canWrite, canRead, canDelete). The conditional action list construction ensures users only see operations they're authorized to perform.


524-545: LGTM!

MaterialTable integration is well-configured with custom Container, detail panel for inline editing, and proper localization. The loading state correctly combines isLoading and deleteMutation.isPending.


546-564: LGTM!

TablePagination is properly configured with server-side pagination controls, i18n support for labels, and appropriate styling. The labelDisplayedRows function handles both known and unknown counts gracefully.

admin-ui/plugins/admin/components/CustomScripts/PersonAuthenticationFields.tsx (1)

28-51: LGTM!

The SAML ACRS multi-select implementation is correct. The type assertion on line 39 is necessary due to reactstrap's typing limitations for select elements.

admin-ui/plugins/admin/components/CustomScripts/hooks/index.ts (1)

1-13: LGTM!

Clean barrel export consolidating the Custom Scripts hooks API for easier imports by consumers.

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

♻️ Duplicate comments (7)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1)

442-456: InputProps usage flagged in previous review.

A past review comment already suggested migrating from InputProps to slotProps.input for MUI v5 forward compatibility.

admin-ui/plugins/admin/components/CustomScripts/PersonAuthenticationFields.tsx (1)

53-71: Hardcoded strings should use i18n.

The label "Interactive" (line 54) and option labels "Web", "Native", "Both methods" (lines 68-70) are hardcoded while other UI text uses t() for internationalization.

admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts (1)

33-33: Double type cast suggests store type mismatch.

The as unknown as RootState pattern bypasses type checking. Consider updating the store's type definitions to return RootState directly.

admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptActions.ts (1)

73-78: Missing queryFn in prefetchQuery will cause runtime failure.

prefetchQuery requires a queryFn to fetch the data. Without it, React Query will throw an error unless this query has been previously cached.

Apply this diff to add the missing queryFn:

  getCustomScriptByType: (payload: { action: LegacyScriptAction }) => {
    const { type, ...params } = payload.action
    queryClient.prefetchQuery({
      queryKey: getGetConfigScriptsByTypeQueryKey(type, params),
+     queryFn: () => getConfigScriptsByType(type, params),
    })
  },

Note: You'll need to import the getConfigScriptsByType function from JansConfigApi.

admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (3)

90-90: Variable shadowing: triggerWebhook shadows imported action creator.

The local constant triggerWebhook returned from useWebhookTrigger() shadows the imported triggerWebhook action creator from line 21, reducing readability.

Consider renaming the local binding:

- const triggerWebhook = useWebhookTrigger()
+ const webhookTrigger = useWebhookTrigger()

Then update usages at lines 100, 131, and 169 to use the new name.


103-103: Avoid JSON.parse(JSON.stringify(...)) for cloning.

This cloning approach loses Date objects, undefined values, Map/Set, and functions. Consider using structuredClone() for a more robust deep clone.

Apply this diff:

- action_data: JSON.parse(JSON.stringify(variables.data)) as Record<string, unknown>,
+ action_data: structuredClone(variables.data) as Record<string, unknown>,

Also applies to line 134 in useUpdateCustomScript.


224-227: Returning hook references may lead to Rules of Hooks violations.

Returning hook references (useCustomScripts, useCustomScriptsByType, useCustomScript, useCustomScriptTypes) from useCustomScriptOperations encourages consumers to call these hooks conditionally or in loops, violating React's Rules of Hooks.

Consider either:

  1. Remove these from the return object and have consumers import hooks directly
  2. Call these hooks at the top level and return their results

For example, if consumers need dynamic script fetching, consider:

  return {
-   useScripts: useCustomScripts,
-   useScriptsByType: useCustomScriptsByType,
-   useScript: useCustomScript,
-   useScriptTypes: useCustomScriptTypes,
    createScript: createMutation,
    updateScript: updateMutation,
    deleteScript: deleteMutation,
    scriptTypes: scriptTypesQuery.data || [],
    scriptTypesLoading: scriptTypesQuery.isLoading,
  }

Consumers should import and call useCustomScripts, useCustomScriptsByType, etc. directly at the component's top level.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57db7f5 and f2a3cea.

📒 Files selected for processing (17)
  • admin-ui/app/utils/TokenController.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptAddPage.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptDetailPage.tsx (2 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptEditPage.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx (10 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/PersonAuthenticationFields.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/helper/utils.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/index.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptActions.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/types/actions.ts (0 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/types/index.ts (0 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/types/state.ts (0 hunks)
💤 Files with no reviewable changes (3)
  • admin-ui/plugins/admin/components/CustomScripts/types/index.ts
  • admin-ui/plugins/admin/components/CustomScripts/types/state.ts
  • admin-ui/plugins/admin/components/CustomScripts/types/actions.ts
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptAddPage.tsx
  • admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptActions.ts
🧬 Code graph analysis (8)
admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (2)
admin-ui/plugins/admin/redux/features/types/customScript.ts (1)
  • CustomScriptItem (29-46)
admin-ui/plugins/admin/components/CustomScripts/types/customScript.ts (1)
  • CustomScriptItem (29-49)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptEditPage.tsx (2)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (2)
  • useCustomScript (77-86)
  • useUpdateCustomScript (113-142)
admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts (1)
  • useMutationEffects (15-52)
admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts (2)
admin-ui/app/utils/TokenController.ts (2)
  • AdditionalPayload (10-21)
  • addAdditionalData (49-124)
admin-ui/app/redux/api/backend-api.ts (1)
  • postUserAction (51-69)
admin-ui/plugins/admin/components/CustomScripts/PersonAuthenticationFields.tsx (4)
admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (1)
  • FormValues (16-31)
admin-ui/plugins/admin/components/CustomScripts/constants.ts (1)
  • SAML_ACRS_OPTIONS (11-15)
admin-ui/plugins/admin/components/CustomScripts/helper/utils.ts (1)
  • getModuleProperty (6-13)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts (2)
admin-ui/plugins/admin/components/CustomScripts/hooks/index.ts (1)
  • useMutationEffects (15-15)
admin-ui/plugins/admin/redux/sagas/ApiPermissionSaga.js (1)
  • errorMessage (100-100)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptAddPage.tsx (3)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1)
  • useCreateCustomScript (88-111)
admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts (1)
  • useMutationEffects (15-52)
admin-ui/plugins/admin/components/CustomScripts/types/actions.ts (1)
  • SubmitData (5-7)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (3)
admin-ui/plugins/admin/redux/sagas/WebhookSaga.ts (1)
  • triggerWebhook (279-368)
admin-ui/plugins/admin/components/CustomScripts/constants.ts (1)
  • SCRIPT_CACHE_CONFIG (3-9)
admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts (1)
  • logAuditAction (28-47)
admin-ui/plugins/admin/components/CustomScripts/helper/utils.ts (2)
admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (1)
  • FormValues (16-31)
admin-ui/app/utils/Util.ts (1)
  • filterEmptyObjects (82-84)
🔇 Additional comments (33)
admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (1)

6-14: Type union approach is reasonable for migration.

The union types CustomScriptItem | CustomScript enable gradual migration from manually-created types to generated types. The async return type addition for handleSubmit correctly supports mutation-based flows.

Note: Components consuming these props may need type guards when accessing CustomScriptItem-specific fields like action_message, script_path, or location_type that don't exist on CustomScript.

admin-ui/plugins/admin/components/CustomScripts/CustomScriptDetailPage.tsx (1)

16-116: LGTM!

The shorthand fragment syntax (<>...</>) is idiomatic React and equivalent to the explicit React.Fragment. No behavioral changes.

admin-ui/app/utils/TokenController.ts (1)

10-21: LGTM!

Exporting AdditionalPayload enables its use in the new audit utilities without duplicating the type definition.

admin-ui/plugins/admin/components/CustomScripts/CustomScriptAddPage.tsx (2)

46-46: Empty object passed as item prop.

Passing {} as item is appropriate for the "Add" flow. However, since item is typed as CustomScriptItem | CustomScript, TypeScript should accept an empty object. Ensure CustomScriptForm handles the empty/undefined field cases gracefully.


30-36: I'll help you verify the review comment about unused variables and type assertions. Let me investigate the CustomScript type definition and the code context.
<function_calls>


#!/bin/bash

Find CustomScript type definition

rg -n "type CustomScript|interface CustomScript" --type ts --type tsx -A 15


</function_calls>


#!/bin/bash

Locate the file under review

find . -type f -name "CustomScriptAddPage.tsx" 2>/dev/null


</function_calls>
<function_calls>


#!/bin/bash

Read the CustomScriptAddPage.tsx file to see imports and full context

file_path=$(find . -type f -name "CustomScriptAddPage.tsx" 2>/dev/null | head -1)
if [ -n "$file_path" ]; then
wc -l "$file_path"
fi


</function_calls>
<function_calls>


#!/bin/bash

Read first 80 lines of the file to see imports and component structure

file_path=$(find . -type f -name "CustomScriptAddPage.tsx" 2>/dev/null | head -1)
if [ -n "$file_path" ]; then
head -80 "$file_path" | cat -n
fi


</function_calls>
<function_calls>


#!/bin/bash

Search for where CustomScript is imported from

rg -n "import.*CustomScript|from.*CustomScript" --type ts --type tsx | head -20


</function_calls>
<function_calls>


#!/bin/bash

Look for type definition files or generated API types

find . -type f ( -name ".d.ts" -o -name "types" -o -name "api" ) -path "/CustomScript*" 2>/dev/null | head -20


</function_calls>
<function_calls>


#!/bin/bash

More comprehensive search for CustomScript definition

rg -n "CustomScript\s*[=:{]" --type ts --type tsx | head -30


</function_calls>

admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (3)

150-169: Delete confirmation handler is well-structured.

The handleDeleteConfirm properly validates itemToDelete?.inum before proceeding, uses async/await with proper error handling, and provides user feedback via toast notifications. The cleanup of modal state on success is correct.


402-426: Good error boundary pattern.

The error handling renders a user-friendly message with the actual error details and provides a retry action. This is a solid pattern for handling query failures.


568-578: Delete dialog correctly guarded.

The GluuDialog is properly conditionally rendered only when canDelete && itemToDelete are truthy, preventing unnecessary renders and ensuring the dialog has valid data.

admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts (3)

1-4: Good: Proper import of AdditionalPayload type.

The import from Utils/TokenController correctly reuses the existing type definition, avoiding duplication.


6-26: LGTM: Defensive audit log creation.

The createAuditLog function properly validates required auth data before creating the log and returns null with a warning when data is missing.


42-46: Good: Handles postUserAction returning -1 on failure.

The error handling correctly checks for the -1 return value from postUserAction and logs an appropriate error message.

admin-ui/plugins/admin/components/CustomScripts/CustomScriptEditPage.tsx (3)

1-12: LGTM: Clean imports and hook-based architecture.

Good migration from Redux state to React Query hooks. The imports are well-organized and the component now uses proper data-fetching patterns.


18-20: Good: Proper use of useSearchParams.

Using React Router's useSearchParams instead of directly accessing window.location.search ensures reactive updates on navigation.


50-79: LGTM: Proper loading and error state handling.

The component correctly handles loading states with a loader UI and provides meaningful error messages when script fetching fails.

admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts (1)

8-13: LGTM: Well-typed generic interface.

The interface properly exposes type parameters for flexibility and provides sensible defaults.

admin-ui/plugins/admin/components/CustomScripts/helper/utils.ts (3)

6-13: LGTM: Defensive property lookup with broadened signature.

The function properly handles undefined properties and the broadened type signature accommodates both ModuleProperty[] and SimpleCustomProperty[].


28-28: Good: Uses nullish coalescing for level.

Using ?? instead of || correctly preserves a valid level of 0.


31-33: Good: Correct type cast for configurationProperties.

The cast to ConfigurationProperty[] aligns with the FormValues interface definition.

admin-ui/plugins/admin/components/CustomScripts/PersonAuthenticationFields.tsx (2)

11-16: LGTM: Well-defined props interface.

The interface clearly defines the component's dependencies and uses proper TypeScript types.


73-77: LGTM: Validation error display.

Properly shows formik validation errors for moduleProperties when touched.

admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx (8)

38-38: Good: Removed unused isSubmitting prop.

The component now correctly uses only formik.isSubmitting for loading state.


45-47: LGTM: Proper edit mode detection and hook usage.

The isEditMode flag correctly determines if editing an existing script, and useCustomScriptTypes replaces Redux state access.


287-305: LGTM: Error alert with action button.

Good use of MUI Alert with an action button for showing script errors. The styling is consistent with the custom color scheme.


354-361: LGTM: Clean component extraction.

Extracting PersonAuthenticationFields improves maintainability and reduces the complexity of this form component.


380-380: LGTM: Prevent script type changes in edit mode.

Disabling scriptType when isEditMode is true prevents potentially breaking changes to existing scripts.


421-426: LGTM: Using constants for programming languages.

Replacing inline options with PROGRAMMING_LANGUAGES constant improves maintainability.


452-456: LGTM: Localized location type options.

Using LOCATION_TYPE_OPTIONS with t(location.key) properly supports i18n for location type labels.


141-159: I'll verify the review comment about the potential stale closure in the useCallback dependency array. Let me start by examining the codebase for similar patterns and understanding how Formik is used in this project.
<function_calls>

#!/bin/bash

Check if there are similar patterns in the codebase for comparison

rg -n "useCallback.*formik.(values|setFieldValue)" --type=ts --type=tsx -C2


</function_calls>
<function_calls>

#!/bin/bash

Let's examine the file in question to understand the full context

wc -l admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx


</function_calls>
<function_calls>

#!/bin/bash

Read the specific section and surrounding context

sed -n '120,170p' admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx


</function_calls>
<function_calls>

#!/bin/bash

Look for how formik is used in this file

rg -n "formik." admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx -C1 | head -50


</function_calls>

admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptActions.ts (1)

14-60: LGTM: Well-structured action hook.

The useCustomScriptActions hook provides a clean API for CRUD operations with appropriate status flags and refetch helpers. The async wrappers and invalidation strategies follow React Query best practices.

admin-ui/plugins/admin/components/CustomScripts/hooks/index.ts (1)

1-15: LGTM: Clean barrel export pattern.

The consolidated export surface provides a clean public API for CustomScripts hooks, making them easier to consume across the application.

admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (3)

26-48: LGTM: Clean interfaces and safe webhook wrapper.

The ScriptType and WebhookPayload interfaces are well-defined. The useWebhookTrigger hook provides a safe wrapper with appropriate error handling.


50-86: LGTM: Consistent fetch hooks with proper caching.

The fetch hooks (useCustomScripts, useCustomScriptsByType, useCustomScript) follow a consistent pattern with auth token checks and appropriate cache configurations.


180-215: LGTM: Robust script type transformation with defensive checks.

The useCustomScriptTypes hook includes thorough null/undefined checks and handles various formatting cases (underscore-delimited, simple types). The extended cache times are appropriate for infrequently changing data.

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: 3

♻️ Duplicate comments (4)
admin-ui/plugins/admin/components/CustomScripts/PersonAuthenticationFields.tsx (2)

54-70: Hardcoded strings should use i18n.

The label "Interactive" (line 54) and option labels "Web", "Native", "Both methods" (lines 68-70) are hardcoded while other UI text in this component uses t() for internationalization.

Apply this diff and add corresponding translation keys to locale files:

       <FormGroup row>
-        <GluuLabel label="Interactive" required doc_category={SCRIPT} doc_entry="usage_type" />
+        <GluuLabel label="fields.interactive" required doc_category={SCRIPT} doc_entry="usage_type" />
         <Col sm={9}>
           <InputGroup>
             <CustomInput
               // ...
             >
               <option value="">{t('options.choose')}...</option>
-              <option value="interactive">Web</option>
-              <option value="service">Native</option>
-              <option value="both">Both methods</option>
+              <option value="interactive">{t('options.web')}</option>
+              <option value="service">{t('options.native')}</option>
+              <option value="both">{t('options.both_methods')}</option>
             </CustomInput>

38-41: Type casting workaround for select element.

The double cast through unknown is a workaround for the component library's typing. If the Input component supports ChangeEvent<HTMLSelectElement> for type="select", prefer using that directly.

admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1)

439-452: Consider migrating from InputProps to slotProps.input.

In MUI v5, InputProps is being phased out in favor of slotProps.input for forward compatibility with MUI v6.

admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1)

88-111: Variable shadowing: triggerWebhook shadows imported action creator.

The local triggerWebhook from useWebhookTrigger() shadows the imported triggerWebhook at line 21. This was flagged in a previous review.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f2a3cea and 4d55e03.

📒 Files selected for processing (10)
  • admin-ui/app/context/theme/config.ts (4 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptAddPage.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptEditPage.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/PersonAuthenticationFields.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/types/actions.ts (0 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/types/customScript.ts (0 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • admin-ui/plugins/admin/components/CustomScripts/types/actions.ts
  • admin-ui/plugins/admin/components/CustomScripts/types/customScript.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptAddPage.tsx
  • admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts
🧬 Code graph analysis (7)
admin-ui/app/context/theme/config.ts (1)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptEditPage.tsx (3)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (2)
  • useCustomScript (77-86)
  • useUpdateCustomScript (113-142)
admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts (1)
  • useMutationEffects (15-46)
admin-ui/plugins/admin/components/CustomScripts/types/actions.ts (1)
  • SubmitData (3-5)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptAddPage.tsx (2)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1)
  • useCreateCustomScript (88-111)
admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts (1)
  • useMutationEffects (15-46)
admin-ui/plugins/admin/components/CustomScripts/PersonAuthenticationFields.tsx (4)
admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (1)
  • FormValues (14-29)
admin-ui/plugins/admin/components/CustomScripts/constants.ts (1)
  • SAML_ACRS_OPTIONS (11-15)
admin-ui/plugins/admin/components/CustomScripts/helper/utils.ts (1)
  • getModuleProperty (6-13)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (4)
admin-ui/plugins/admin/components/CustomScripts/types/customScript.ts (1)
  • ScriptType (22-25)
admin-ui/plugins/admin/redux/sagas/WebhookSaga.ts (1)
  • triggerWebhook (279-368)
admin-ui/plugins/admin/components/CustomScripts/constants.ts (1)
  • SCRIPT_CACHE_CONFIG (3-9)
admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts (1)
  • logAuditAction (28-47)
admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts (2)
admin-ui/plugins/admin/components/CustomScripts/hooks/index.ts (1)
  • useMutationEffects (15-15)
admin-ui/plugins/admin/redux/sagas/ApiPermissionSaga.js (1)
  • errorMessage (100-100)
admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (2)
admin-ui/plugins/admin/components/CustomScripts/types/customScript.ts (1)
  • CustomScriptItem (27-47)
admin-ui/plugins/admin/redux/features/types/customScript.ts (1)
  • CustomScriptItem (29-46)
🔇 Additional comments (24)
admin-ui/app/context/theme/config.ts (1)

8-47: LGTM! Consistent borderColor addition across all themes.

The new borderColor property is correctly added to all four theme configurations with the same value (customColors.lightGray). Since getThemeColor returns typeof themeConfig[keyof typeof themeConfig], the return type automatically includes borderColor, enabling type-safe access without casting in consumers like CustomScriptListPage.tsx.

admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts (1)

34-45: Error handling logic is improved; same re-render concern applies.

The error message extraction now properly handles Error instances, objects with a message property, and falls back to the translated error message. This addresses the previous review feedback well.

The same potential duplicate-trigger concern from the success effect applies here. Consider applying the same ref-based guard pattern.

admin-ui/plugins/admin/components/CustomScripts/PersonAuthenticationFields.tsx (1)

11-23: Well-structured props interface and component setup.

The component correctly encapsulates person authentication-specific fields, properly typed with FormikProps<FormValues>. The extraction of getModuleProperty as a prop allows flexibility in how module properties are accessed.

admin-ui/plugins/admin/components/CustomScripts/CustomScriptAddPage.tsx (2)

16-22: Clean mutation integration with reusable effects hook.

The useMutationEffects hook cleanly separates the success/error side effects from the page component. The mutation is properly connected with appropriate translation keys for success and error messages.


30-41: Based on my verification, I can now provide the rewritten review comment:


Type assertion bypasses TypeScript validation, but form validation mitigates the risk.

The assertion scriptData as CustomScript bypasses TypeScript's structural checks. However, this is less critical than initially suggested because the form validation schema (Yup) enforces that required fields (name, scriptType, programmingLanguage, level) are present before submission reaches this point.

The destructuring removes only UI-specific fields (action_message, script_path, location_type), not core required fields. The real concern is type safety rather than runtime integrity—CustomScriptItem (local type) has all optional properties, while CustomScript (from JansConfigApi) likely expects required fields.

Consider strengthening the type relationship instead of adding redundant runtime checks:

-      await createMutation.mutateAsync({
-        data: scriptData as CustomScript,
-        actionMessage: action_message,
-      })
+      // Type is ensured by form validation; consider updating CustomScriptItem
+      // interface to reflect required fields or using a type guard at form level
+      await createMutation.mutateAsync({
+        data: scriptData as CustomScript,
+        actionMessage: action_message,
+      })

Alternatively, define an intermediate type that explicitly reflects what CustomScript requires:

type ValidatedCustomScript = Required<Pick<CustomScript, 'name' | 'scriptType' | 'programmingLanguage' | 'level'>> & Omit<CustomScript, 'name' | 'scriptType' | 'programmingLanguage' | 'level'>
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (6)

79-97: Permission handling is properly structured.

Direct constant assignment for scriptsResourceId and scriptScopes addresses the prior review feedback. The useMemo hooks for permission checks are appropriate since they depend on hook functions. The authorizeHelper effect correctly runs when dependencies change.


147-166: Delete confirmation flow handles success/error appropriately.

The delete flow correctly:

  • Guards against missing inum
  • Closes the modal and clears state on success
  • Extracts error messages with proper fallback
  • Uses local toast dispatch (appropriate since modal state needs updating on success)

308-371: Table actions properly gated by permissions.

Actions are conditionally added based on canWrite, canRead, and canDelete permissions. The type assertions rowData as CustomScript are necessary due to MaterialTable's union type (T | T[]) for row data in action handlers, and are safe here since selection is disabled.


399-423: Good error state handling with recovery option.

The error UI properly extracts error messages and provides a retry button for user recovery. The error message extraction pattern is consistent with other error handling in this PR.


521-542: MaterialTable integration is correct.

The table setup properly configures:

  • Loading state combining query and delete mutation pending states
  • Custom container removing elevation
  • Detail panel for expandable row details
  • Localization for empty state message

543-561: Pagination correctly configured with theme-aware styling.

The borderColor access (themeColors.borderColor ?? '#e0e0e0') is now clean after the theme config changes. Pagination state is properly connected with callbacks for page/rows-per-page changes.

admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (2)

5-6: Type inconsistency between item and handleSubmit parameter.

The item prop accepts CustomScript, but handleSubmit expects { customScript: CustomScriptItem }. If a CustomScript object has properties not present in CustomScriptItem (or vice versa), the form may submit incomplete or mistyped data.

Consider aligning the types:

 export interface CustomScriptFormProps {
   item: CustomScriptItem | CustomScript
-  handleSubmit: (data: { customScript: CustomScriptItem }) => void | Promise<void>
+  handleSubmit: (data: { customScript: CustomScriptItem | CustomScript }) => void | Promise<void>
   viewOnly?: boolean
 }

Alternatively, ensure the form internally normalizes CustomScript to CustomScriptItem before invoking handleSubmit.


10-12: LGTM!

The row type update to CustomScriptItem | CustomScript aligns with the item prop change and supports the new data flow from API hooks.

admin-ui/plugins/admin/components/CustomScripts/CustomScriptEditPage.tsx (5)

1-12: LGTM!

Clean import refactoring that removes Redux dependencies in favor of the new hook-based architecture. The imports are well-organized and include proper type imports.


22-30: LGTM!

Good use of the custom hooks. The useMutationEffects hook provides standardized toast notifications and navigation, keeping the component clean.


67-84: LGTM!

Defensive error handling with proper fallback messages. The error message extraction handles various error shapes appropriately.


86-94: LGTM!

Clean render structure with the loader appropriately tied to the mutation's pending state. The form correctly receives the fetched script data.


46-49: I'll verify the safety of the type cast in the custom script handling code. Let me start by exploring the type definitions involved.
<function_calls>

#!/bin/bash

Find CustomScript and CustomScriptItem type definitions

rg -n "export (interface|type) CustomScript" --type ts -C 5


</function_calls>

Awaiting results to examine the type definitions...

admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (6)

1-24: LGTM!

Well-organized imports covering React Query, Redux integration, API hooks, and audit utilities. The import structure supports the hook-based architecture cleanly.


35-48: LGTM!

The useWebhookTrigger hook properly memoizes the callback with useCallback and includes dispatch in the dependency array.


50-86: LGTM!

Well-structured data fetching hooks with proper auth-token gating and cache configuration. The enabled conditions prevent unnecessary API calls when required parameters are missing.


158-168: LGTM!

Safe queryKey handling with proper type guards before calling startsWith. This addresses the previous review concern about unsafe casting.


183-218: LGTM!

Well-implemented select function with defensive handling for edge cases (null data, empty strings, underscore-separated names). The longer stale time is appropriate for script types which change infrequently.


226-237: The concern about Rules of Hooks violations is not applicable—useCustomScriptOperations is unused dead code.

Investigation reveals that:

  • useCustomScriptOperations is never called anywhere in the codebase
  • No component imports or invokes this hook
  • All components import individual hooks directly (useCustomScriptsByType, useDeleteCustomScript, etc.) instead
  • The returned hook functions are never executed, so there is no possibility of conditional or loop-based invocation

While returning hooks from hooks can theoretically violate React's Rules of Hooks if misused, this code path is not taken in practice. The hook is exported but unused, making it dead code rather than a functional concern.

Consider removing useCustomScriptOperations entirely, or document its purpose if it's intended for future use or as a convenience API for external consumers.

@syntrydy syntrydy changed the title fix(admin-ui): Use typescript generated SCRIPTS pages #2464 fix(admin-ui): Use typescript generated SCRIPTS pages Nov 27, 2025
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: 3

♻️ Duplicate comments (1)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1)

143-180: Variable shadowing; query invalidation looks good.

Line 145: Same variable shadowing issue — rename to webhookTrigger for consistency.

The predicate-based query invalidation (lines 157-167) correctly uses type guards to safely handle queryKey, addressing previous unsafe casting concerns.

Apply this diff:

 export function useDeleteCustomScript() {
   const queryClient = useQueryClient()
-  const triggerWebhook = useWebhookTrigger()
+  const webhookTrigger = useWebhookTrigger()
   const baseMutation = useDeleteConfigScriptsByInum()

   return {
     ...baseMutation,
     mutateAsync: async (variables: { inum: string; actionMessage?: string }) => {
       const { actionMessage, ...baseVariables } = variables
       const result = await baseMutation.mutateAsync(baseVariables)

       await Promise.all([
         queryClient.invalidateQueries({ queryKey: getGetConfigScriptsQueryKey() }),
         queryClient.invalidateQueries({
           predicate: (query) => {
             const queryKey = query.queryKey
             if (!Array.isArray(queryKey) || typeof queryKey[0] !== 'string') {
               return false
             }
             const key = queryKey[0]
             return (
               key.startsWith('/api/v1/config/scripts/type/') ||
               key.startsWith('/api/v1/config/scripts/')
             )
           },
         }),
       ])

-      triggerWebhook({ createdFeatureValue: { inum: variables.inum } })
+      webhookTrigger({ createdFeatureValue: { inum: variables.inum } })
       await logAuditAction(DELETION, SCRIPT, {
         action: { action_data: { inum: variables.inum } },
         message: actionMessage,
       })

       return result
     },
   }
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d55e03 and 14f4b98.

📒 Files selected for processing (2)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts (1)
admin-ui/plugins/admin/components/CustomScripts/hooks/index.ts (1)
  • useMutationEffects (15-15)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: label PR
🔇 Additional comments (5)
admin-ui/plugins/admin/components/CustomScripts/hooks/useMutationEffects.ts (1)

1-64: LGTM! Mutation effects implementation is solid.

The hook correctly addresses previous concerns:

  • Uses persistent refs (successHandledRef, errorHandledRef) to prevent duplicate side effects during re-renders
  • Properly resets handled flags when mutation returns to idle state
  • Enhanced error type checking handles Error instances, objects with message properties, and falls back to translated error messages
  • Dependencies are correctly specified in both effects
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (4)

1-32: LGTM! Imports and type definitions are well-organized.

The ScriptType is correctly imported from the types file rather than redefined, addressing the previous duplicate type concern.


34-47: LGTM! Webhook trigger with proper error handling.

The utility hook correctly wraps webhook dispatch in error handling to prevent failures from disrupting mutation flows.


49-85: LGTM! Query hooks are properly configured.

All three fetch hooks correctly:

  • Gate queries on auth token presence
  • Use consistent cache configuration from SCRIPT_CACHE_CONFIG
  • Comply with React Query v5 (no deprecated callbacks)

182-217: LGTM! Script types hook with safe data transformation.

The useCustomScriptTypes hook correctly:

  • Gates on auth token
  • Safely handles empty/invalid data
  • Transforms script type identifiers to user-friendly names
  • Uses appropriate cache configuration

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 14f4b98 and 396134f.

📒 Files selected for processing (1)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (4)
admin-ui/plugins/admin/redux/sagas/WebhookSaga.ts (1)
  • triggerWebhook (279-368)
admin-ui/plugins/admin/components/CustomScripts/constants.ts (1)
  • SCRIPT_CACHE_CONFIG (3-9)
admin-ui/plugins/admin/components/CustomScripts/hooks/auditUtils.ts (1)
  • logAuditAction (28-47)
admin-ui/plugins/admin/components/CustomScripts/types/customScript.ts (1)
  • ScriptType (22-25)
🔇 Additional comments (1)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1)

1-232: Excellent refactoring—all previous critical issues addressed!

The implementation now follows React Query v5 best practices and all major concerns from previous reviews have been resolved:

  • ✅ Removed deprecated onSuccess/onError callbacks
  • ✅ Fixed variable shadowing (webhookTrigger instead of triggerWebhook)
  • ✅ Replaced brittle JSON.parse(JSON.stringify()) with structuredClone()
  • ✅ Added proper type guards for queryKey access (lines 158-161)
  • ✅ Using canonical query key getters (getGetConfigScriptsByInumQueryKey)
  • ✅ Eliminated duplicate ScriptType definition by importing from types
  • ✅ Removed hook references from useCustomScriptOperations return (Rules of Hooks compliant)

The hooks are well-structured with:

  • Proper auth gating on all queries
  • Appropriate cache configuration (staleTime/gcTime)
  • Comprehensive cache invalidation strategies
  • Webhook triggering with error handling
  • Audit logging for all mutations

Copy link
Contributor

@duttarnab duttarnab left a comment

Choose a reason for hiding this comment

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

  1. Can we remove the horizontal scroll.
    https://www.loom.com/share/872fe718d6414024b911147d10ccadbc
  2. Heading are not visible
image
  1. Selected rows fields are not visible
image 4. Texts in the table footer are not visible: image 5. I have enabled `Twillo_sms` script but changes are not reflected on Scripts list page. Please make sure all the changed fields should be correctly reflected on list page after saving. image image
  1. I have added a webhook on add/edit of script. The webhooks dialog opened after editing a script has disabled accept button.
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: 2

♻️ Duplicate comments (1)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1)

435-457: TextField adornments still using deprecated InputProps API (optional).

MUI v5 favors slotProps.input over InputProps for start/end adornments. This is already noted in an earlier review; consider migrating when convenient to stay aligned with the newer API surface.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 396134f and 7916c7b.

📒 Files selected for processing (2)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (1)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1)

230-243: Aggregated useCustomScriptOperations surface looks good and focused.

The operations hook cleanly bundles the three mutations plus script type data/loading flags without re‑exposing any hook references, which avoids Rules‑of‑Hooks pitfalls and keeps the API small and purposeful.

@syntrydy
Copy link
Contributor Author

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

♻️ Duplicate comments (1)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1)

452-474: Prefer slotProps.input over InputProps on TextField (duplicate of prior nit).

MUI v5 has been moving away from InputProps on TextField in favor of slotProps.input. For forward compatibility, consider migrating the adornments:

-              <TextField
+              <TextField
                 size="small"
                 label={t('fields.search')}
                 placeholder={t('placeholders.search_scripts')}
                 value={pattern}
                 onChange={handlePatternChange}
                 onKeyDown={handlePatternKeyDown}
-                InputProps={{
-                  startAdornment: (
-                    <InputAdornment position="start">
-                      <SearchIcon fontSize="small" />
-                    </InputAdornment>
-                  ),
-                  endAdornment: pattern && (
-                    <InputAdornment position="end">
-                      <IconButton size="small" onClick={handleSearchClear} edge="end">
-                        <ClearIcon fontSize="small" />
-                      </IconButton>
-                    </InputAdornment>
-                  ),
-                }}
+                slotProps={{
+                  input: {
+                    startAdornment: (
+                      <InputAdornment position="start">
+                        <SearchIcon fontSize="small" />
+                      </InputAdornment>
+                    ),
+                    endAdornment: pattern && (
+                      <InputAdornment position="end">
+                        <IconButton size="small" onClick={handleSearchClear} edge="end">
+                          <ClearIcon fontSize="small" />
+                        </IconButton>
+                      </InputAdornment>
+                    ),
+                  },
+                }}
                 sx={{ minWidth: 300 }}
               />

This keeps behavior identical while aligning with the newer MUI API.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7916c7b and 2ed1771.

📒 Files selected for processing (1)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1 hunks)
🔇 Additional comments (4)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (4)

78-97: Permissions and query wiring look consistent with objectives.

Using ADMIN_UI_RESOURCES.Scripts with CEDAR_RESOURCE_SCOPES, hasCedar*Permission, and authorizeHelper plus GluuViewWrapper gives clear, centralized access control for the page, and useCustomScriptsByType is parameterized cleanly with limit, startIndex, pattern, sortBy, and sortOrder. This matches the move away from Redux toward typed hooks and looks solid.

Also applies to: 99-118, 449-449


141-165: Ensure delete mutation also refreshes the list.

handleDeleteConfirm shows a toast and closes the dialog on success, but the list is only refreshed when the user explicitly clicks the refresh icon. If useDeleteCustomScript does not already invalidate the relevant query, the deleted script may remain visible until a manual refresh.

Please confirm that useDeleteCustomScript is invalidating the same query key used by useCustomScriptsByType (or call refetch on success here) so the table always reflects the current backend state after a delete.

Also applies to: 590-600


176-200: Confirm sortOrder string values match the API contract.

You’re sending sortOrder as 'ascending' | 'descending' when sortBy is set. This is fine as long as the generated client / backend expects those exact string values (not e.g. 'asc' | 'desc').

Please double‑check the generated TypeScript client types or API docs for the sort order enum and adjust the toggling logic if necessary.

Also applies to: 104-110


211-324: Table configuration, theming, and detail panel integration look well-structured.

The column definitions, action wiring, rowStyle highlighting for errored/disabled scripts, theme‑aware header and pagination styling, and the detailPanel integration with CustomScriptDetailPage are all cohesive and readable. This is a nice, idiomatic use of @material-table/core and MUI theming in this context.

Also applies to: 391-417, 541-562, 563-586

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: 2

♻️ Duplicate comments (1)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1)

453-475: Migrate TextField adornments from InputProps to slotProps.input (MUI v5+)

The search TextField still uses InputProps for adornments, which MUI v5 is steering away from in favor of slotProps.input. This is the same concern raised in a prior review on this file.

You can future‑proof this by shifting the adornments into slotProps.input:

-              <TextField
+              <TextField
                 size="small"
                 label={t('fields.search')}
                 placeholder={t('placeholders.search_scripts')}
                 value={pattern}
                 onChange={handlePatternChange}
                 onKeyDown={handlePatternKeyDown}
-                InputProps={{
-                  startAdornment: (
-                    <InputAdornment position="start">
-                      <SearchIcon fontSize="small" />
-                    </InputAdornment>
-                  ),
-                  endAdornment: pattern && (
-                    <InputAdornment position="end">
-                      <IconButton size="small" onClick={handleSearchClear} edge="end">
-                        <ClearIcon fontSize="small" />
-                      </IconButton>
-                    </InputAdornment>
-                  ),
-                }}
+                slotProps={{
+                  input: {
+                    startAdornment: (
+                      <InputAdornment position="start">
+                        <SearchIcon fontSize="small" />
+                      </InputAdornment>
+                    ),
+                    endAdornment: pattern && (
+                      <InputAdornment position="end">
+                        <IconButton size="small" onClick={handleSearchClear} edge="end">
+                          <ClearIcon fontSize="small" />
+                        </IconButton>
+                      </InputAdornment>
+                    ),
+                  },
+                }}
                 sx={{ minWidth: 300 }}
               />

If MUI’s typings complain, you may need to slightly adjust the slotProps.input type (e.g., with a narrow cast) based on the installed @mui/material version.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2ed1771 and 5fb4834.

📒 Files selected for processing (1)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (6)
admin-ui/plugins/admin/components/CustomScripts/types/customScript.ts (1)
  • ScriptError (18-20)
admin-ui/app/utils/pagingUtils.ts (1)
  • getPagingSize (1-24)
admin-ui/plugins/admin/components/CustomScripts/constants.ts (1)
  • DEFAULT_SCRIPT_TYPE (1-1)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (3)
  • useCustomScriptsByType (61-74)
  • useCustomScriptTypes (193-228)
  • useDeleteCustomScript (154-191)
admin-ui/plugins/admin/components/CustomScripts/hooks/index.ts (3)
  • useCustomScriptsByType (3-3)
  • useCustomScriptTypes (8-8)
  • useDeleteCustomScript (7-7)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)

@syntrydy syntrydy requested a review from duttarnab December 1, 2025 01:36
@@ -1,11 +1,11 @@
// @ts-nocheck
Copy link
Contributor

Choose a reason for hiding this comment

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

we shall remove this, otherwise compiler wont be able to check the types of this file

@@ -1,6 +1,6 @@
// @ts-nocheck
Copy link
Contributor

Choose a reason for hiding this comment

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

we shall remove this, otherwise compiler wont be able to check the types of this file

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

Caution

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

⚠️ Outside diff range comments (4)
admin-ui/app/utils/Util.ts (1)

86-96: Consider trimming and conditionally including description

Right now description is forwarded as‑is and the property is always present (possibly undefined), while the type marks it as optional. For consistency with key/value and to better reflect the optional contract, you can trim and only include it when defined/non‑empty.

-export const mapPropertyToKeyValue = (prop: {
-  key?: string
-  value?: string
-  value1?: string
-  value2?: string
-  description?: string
-}): { key: string; value: string; description?: string } => {
-  const key = (prop.key ?? prop.value1 ?? '').trim()
-  const value = (prop.value ?? prop.value2 ?? '').trim()
-  return { key, value, description: prop.description }
-}
+export const mapPropertyToKeyValue = (prop: {
+  key?: string
+  value?: string
+  value1?: string
+  value2?: string
+  description?: string
+}): { key: string; value: string; description?: string } => {
+  const key = (prop.key ?? prop.value1 ?? '').trim()
+  const value = (prop.value ?? prop.value2 ?? '').trim()
+  const description = prop.description?.trim()
+
+  return description !== undefined && description !== ''
+    ? { key, value, description }
+    : { key, value }
+}
admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx (3)

61-75: Verify property normalization for Custom/Module properties (likely linked to “empty custom properties” bug)

transformPropertyForApi normalizes both { key, value } and { value1, value2 } into { value1, value2, hide, description }, while configurationPropertiesOptions/modulePropertiesOptions derive options from formik.values.* (produced by transformToFormValues) and feed them into GluuProperties. If transformToFormValues does not perform the inverse normalization (i.e., consistently mapping both key/value and value1/value2 from the TS client into the shape expected by mapPropertyToKeyValue/GluuProperties), some properties can show with empty keys/values or not show at all, which matches the QA report.

Please double-check that transformToFormValues is symmetric with transformPropertyForApi for ConfigurationProperty and ModuleProperty, so legacy data using either field pair renders correctly in the form. I can help sketch a symmetric mapping if it’s not already there.

Also applies to: 263-269, 505-522


219-227: Clearing script_path leaves stale locationPath/location_path module property

When the user clears the script path input, scriptPathChange early-returns on a falsy value and never clears locationPath or the 'location_path' entry in moduleProperties, so those stay at the last non-empty value while script_path becomes ''. Even if validation typically prevents saving an empty path for file location type, this leaves inconsistent form state and can be surprising.

You can fix this by explicitly clearing locationPath and removing the module property when value is empty:

   const scriptPathChange = useCallback(
     (value: string): void => {
-      if (!value) return
-      formik.setFieldValue('locationPath', value)
-      removeModuleProperty('location_path')
-      updateModuleProperty('location_path', value)
+      if (!value) {
+        formik.setFieldValue('locationPath', undefined)
+        removeModuleProperty('location_path')
+        return
+      }
+
+      formik.setFieldValue('locationPath', value)
+      removeModuleProperty('location_path')
+      updateModuleProperty('location_path', value)
     },
     [formik.setFieldValue, removeModuleProperty, updateModuleProperty],
   )

Also applies to: 471-481


564-576: disableApply logic prevents users from submitting Add Script form

On the Add Script page, multiple required fields start empty (name, scriptType, script_path when location_type defaults to 'file'), triggering validation failures on mount. The condition disableApply={!formik.isValid || !formik.dirty} keeps the Apply button permanently disabled until all validation errors clear, even though inline validation errors are displayed for each field.

Two improvements:

  1. Add location_type to the validation schema. The field is currently used in conditional .when() checks (lines 16, 20 in validations.ts) but is not defined in Yup.object(), which can cause inconsistent validation tracking.

  2. Consider loosening the Apply button gate. If you want to allow submission and let the API reject invalid data, or to rely on inline error displays rather than blocking the button:

-            disableApply={!formik.isValid || !formik.dirty}
+            disableApply={!formik.dirty}

This removes the isValid check and still prevents no-op submissions (when nothing has changed). Validation errors will still display inline, and the API can provide feedback on any remaining issues.

♻️ Duplicate comments (1)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1)

424-446: (Repeat nit) Consider migrating TextField adornments to slotProps.input

MUI v5 is steering toward slotProps.input instead of InputProps on TextField. Refactoring the search field adornments into slotProps={{ input: { startAdornment, endAdornment } }} would align this with the newer API and improve forward compatibility, but it’s purely optional and cosmetic.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c3f8b1b and 7773606.

📒 Files selected for processing (4)
  • admin-ui/app/routes/Apps/Gluu/GluuPropertyItem.tsx (2 hunks)
  • admin-ui/app/utils/Util.ts (1 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx (11 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx
🧬 Code graph analysis (2)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx (7)
admin-ui/plugins/admin/components/CustomScripts/types/forms.ts (1)
  • CustomScriptFormProps (4-8)
admin-ui/app/helpers/navigation.ts (1)
  • useAppNavigation (66-95)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (1)
  • useCustomScriptTypes (193-228)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
admin-ui/plugins/admin/components/CustomScripts/PersonAuthenticationFields.tsx (1)
  • PersonAuthenticationFields (18-82)
admin-ui/plugins/admin/components/CustomScripts/helper/utils.ts (1)
  • getModuleProperty (6-13)
admin-ui/plugins/admin/components/CustomScripts/constants.ts (2)
  • PROGRAMMING_LANGUAGES (17-20)
  • LOCATION_TYPE_OPTIONS (22-25)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (5)
admin-ui/plugins/admin/components/CustomScripts/types/customScript.ts (1)
  • ScriptError (18-20)
admin-ui/app/utils/pagingUtils.ts (1)
  • getPagingSize (1-24)
admin-ui/plugins/admin/components/CustomScripts/constants.ts (1)
  • DEFAULT_SCRIPT_TYPE (1-1)
admin-ui/plugins/admin/components/CustomScripts/hooks/index.ts (3)
  • useCustomScriptsByType (3-3)
  • useCustomScriptTypes (8-8)
  • useDeleteCustomScript (7-7)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
🔇 Additional comments (6)
admin-ui/app/routes/Apps/Gluu/GluuPropertyItem.tsx (2)

78-78: LGTM! Layout refinement improves alignment.

The conditional margin application correctly aligns the remove button with the input fields when labels are present, improving the visual layout consistency.


48-49: Remove the unnecessary property.description check or properly add it to the Property type definition.

The placeholder logic accesses property.description, but this field does not exist in the Property type definitions used by GluuProperties. The Property type only includes key/value (or source/destination for multi-properties), so property.description is always undefined and the fallback to valuePlaceholder is used regardless.

Either:

  • Remove the property.description check entirely if it's not needed
  • Or add description?: string to the Property type definitions if description should be supported across all property objects (particularly for configurationProperties which lack this field in the Script types)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (2)

140-160: Delete flow and error handling look solid

The delete confirmation handler correctly guards on itemToDelete.inum, awaits the mutation, shows success/error toasts, and reliably closes/clears dialog state. The added console.error preserves full error context without changing UX, which is useful for debugging multi-step failures. Based on learnings, keeping this logging here is appropriate.


513-549: Detail panel and delete dialog state handling look correct

The detail panel now passes the row object directly into CustomScriptDetailPage, matching the expected row shape, and the delete dialog’s close handler clears both modal and itemToDelete, avoiding stale selection and ensuring clean unmounting when closed. No issues spotted here.

admin-ui/plugins/admin/components/CustomScripts/CustomScriptForm.tsx (2)

12-15: Error alert + modal wiring looks correct

The conditional rendering of the error Alert and the lazy-loaded error modal is coherent: the Alert only shows when a stack trace exists, and the “show error” action cleanly opens the modal via showErrorModal. No issues spotted here.

Also applies to: 276-305


27-32: Typed script types + centralized select options are a solid improvement

Using useCustomScriptTypes with an isEditMode guard for scriptType, and driving language/location selects from PROGRAMMING_LANGUAGES and LOCATION_TYPE_OPTIONS, together with the PersonAuthenticationFields conditional on scriptTypeState, makes this form more consistent and maintainable. This aligns well with the PR goal of moving to TS-generated types.

Also applies to: 45-48, 271-273, 354-361, 363-400, 402-460, 421-427, 452-456

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: 6

♻️ Duplicate comments (1)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1)

424-446: Migrate TextField adornments to slotProps for MUI v5+ forward compatibility

The search TextField still uses InputProps for startAdornment/endAdornment. In MUI v5.15.x this works, but the library is nudging towards slotProps.input for long‑term support.

You can switch to:

-              <TextField
+              <TextField
                 size="small"
                 label={t('fields.search')}
                 placeholder={t('placeholders.search_scripts')}
                 value={pattern}
                 onChange={handlePatternChange}
                 onKeyDown={handlePatternKeyDown}
-                InputProps={{
-                  startAdornment: (
-                    <InputAdornment position="start">
-                      <SearchIcon fontSize="small" />
-                    </InputAdornment>
-                  ),
-                  endAdornment: pattern && (
-                    <InputAdornment position="end">
-                      <IconButton size="small" onClick={handleSearchClear} edge="end">
-                        <ClearIcon fontSize="small" />
-                      </IconButton>
-                    </InputAdornment>
-                  ),
-                }}
+                slotProps={{
+                  input: {
+                    startAdornment: (
+                      <InputAdornment position="start">
+                        <SearchIcon fontSize="small" />
+                      </InputAdornment>
+                    ),
+                    endAdornment: pattern && (
+                      <InputAdornment position="end">
+                        <IconButton size="small" onClick={handleSearchClear} edge="end">
+                          <ClearIcon fontSize="small" />
+                        </IconButton>
+                      </InputAdornment>
+                    ),
+                  },
+                }}
                 sx={{ minWidth: 300 }}
               />

This keeps behavior identical while aligning with MUI’s newer API.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7773606 and 3cfa3bb.

📒 Files selected for processing (1)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx
🧬 Code graph analysis (1)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (6)
admin-ui/plugins/admin/components/CustomScripts/types/customScript.ts (1)
  • ScriptError (18-20)
admin-ui/app/utils/pagingUtils.ts (1)
  • getPagingSize (1-24)
admin-ui/plugins/admin/components/CustomScripts/constants.ts (1)
  • DEFAULT_SCRIPT_TYPE (1-1)
admin-ui/plugins/user-management/types/CommonTypes.ts (1)
  • ThemeContext (13-17)
admin-ui/plugins/admin/components/CustomScripts/hooks/useCustomScriptApi.ts (3)
  • useCustomScriptsByType (61-74)
  • useCustomScriptTypes (193-228)
  • useDeleteCustomScript (154-191)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
🔇 Additional comments (2)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (2)

196-283: Columns rely on scriptError presence; ensure upstream mapping is consistent

The ScriptTableRow interface adds an optional scriptError?: ScriptError, and rowStyle/name column conditionally render based on scriptError?.stackTrace. For scripts where custom properties and errors come from the backend, you’ll want to ensure the list API (or any transformation layer) always sets scriptError consistently (e.g., undefined vs missing vs empty object).

If some scripts don’t surface custom error info while others do, double‑check the mapping logic in the API layer (or query select option) to confirm that:

  • scriptError is populated when the backend returns error metadata.
  • It’s omitted/undefined when there truly is no error.

This may help with the “Custom Properties not appearing” investigation if the same mapping is responsible for both properties and error state.


389-416: Error UI still renders under GluuViewWrapper; confirm behavior for unauthorized users

The error branch wraps the error card in <GluuViewWrapper canShow={canRead}> and returns it whenever error is truthy. This means:

  • If canRead is false but the hook still reports an error (e.g., auth failure), the outer React tree for the page still renders, and GluuViewWrapper is responsible for hiding the content.
  • The high‑level intent seems to be “no read permission → no page content”, while “read permission + fetch error → show error card”.

If GluuViewWrapper fully hides children when canShow={false}, this is fine. If it instead displays some generic “no permission” message, that message will share layout with the error card wrapper. Given prior review comments about aligning error UI with permission gating, it’s worth double‑checking at runtime that:

  • A user without read permission does not see the generic “error loading scripts” card, and
  • Authorized users with a failing API call do see the card as intended.

If there’s any ambiguity, an explicit if (!canRead) return <GluuViewWrapper canShow={false}> before the error branch would make the behavior unambiguous.

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: 2

♻️ Duplicate comments (2)
admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (2)

431-444: Consider using slotProps instead of InputProps.

The TextField still uses the older InputProps API. As noted in previous reviews, MUI v5 is transitioning to slotProps.input for better forward compatibility.


69-70: Redundant modal state increases coupling.

The component maintains both modal and itemToDelete to control dialog visibility. As noted in previous reviews, the presence of itemToDelete alone could drive the dialog's open state, eliminating the need for a separate modal boolean.

Also applies to: 536-548

Also applies to: 536-548

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3cfa3bb and c6e8380.

📒 Files selected for processing (2)
  • admin-ui/app/routes/Apps/Gluu/GluuProperties.tsx (3 hunks)
  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/admin/components/CustomScripts/CustomScriptListPage.tsx

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6e8380 and 65e7c17.

📒 Files selected for processing (1)
  • admin-ui/app/routes/Apps/Gluu/GluuProperties.tsx (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
admin-ui/app/routes/Apps/Gluu/GluuProperties.tsx (2)

68-80: Refactoring successfully eliminates duplication.

The call to syncFormikProperties correctly replaces the inline Formik synchronization logic, as suggested in the previous review. The pattern is consistent across all three handlers (addProperty, changeProperty, removeProperty).

However, verify that the type safety issues flagged in the helper function don't impact the user-reported bugs.


15-34: The identified type assertion issue does not cause the reported user bugs; the data transformation flow is functionally correct despite the type safety concern.

While line 23 of syncFormikProperties contains an unsafe cast of properties to KeyValueProperty without validation, this code path is never executed in current usage. The component defaults (isKeys=true, multiProperties=false) cause the function to execute lines 26-30 instead, which correctly transforms the data to API format {value1, value2}.

The complete data flow works correctly:

  • API provides: {value1, value2, hide?, description?}
  • mapPropertyToKeyValue converts to: {key, value, description?}
  • syncFormikProperties transforms back to: {value1, value2} (via lines 26-30)
  • transformPropertyForApi on submit handles both formats properly

The user-reported bugs likely have different root causes. configurationProperties is notably absent from the Formik validation schema (unlike moduleProperties), which could contribute to form behavior issues, but not through the type assertion mechanism identified in the review.

The code could be improved by:

  1. Adding validation schema for configurationProperties
  2. Explicitly passing isKeys and multiProperties props to document intent
  3. Adding type guards to prevent unsafe casts

However, the current implementation functions correctly for its intended use case.

Likely an incorrect or invalid review comment.

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

♻️ Duplicate comments (1)
admin-ui/app/routes/Apps/Gluu/GluuProperties.tsx (1)

71-73: Duplicate: Missing Formik sync already flagged.

This useEffect only updates local state but doesn't sync to Formik. The issue and solution are already covered in the previous comment on lines 21-41.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 65e7c17 and 9a32e1a.

📒 Files selected for processing (1)
  • admin-ui/app/routes/Apps/Gluu/GluuProperties.tsx (2 hunks)
🔇 Additional comments (1)
admin-ui/app/routes/Apps/Gluu/GluuProperties.tsx (1)

15-20: LGTM: Type guards correctly implemented.

The type guard functions use proper TypeScript patterns with the in operator and type predicates.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 4, 2025

@syntrydy syntrydy requested a review from duttarnab December 4, 2025 05:45
@duttarnab duttarnab merged commit 7c6cbd2 into main Dec 4, 2025
8 checks passed
@duttarnab duttarnab deleted the admin-ui-2464 branch December 4, 2025 15:42
duttarnab pushed a commit that referenced this pull request Dec 5, 2025
)

* fix(admin-ui): Use typescript generated client for Webhooks pages #2433

* fix(admin-ui): Code review #2433

* fix(admin-ui): Code review #2433

* fix(admin-ui): Code review #2433

* fix(admin-ui): Code review #2433

* fix(admin-ui): Code review #2433

* fix(admin-ui): Code review #2433

* fix(admin-ui): Code review #2433

* fix(admin-ui): code review #2478

* fix(admin-ui): code review #2433

* fix(admin-ui): code review #2433

* fix(admin-ui): code review #2433

* fix(admin-ui): code review #2433

* fix(admin-ui): code review #2433

* fix(admin-ui): code review #2433

* fix(admin-ui): code review #2433

* fix(admin-ui): code review #2433
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp-admin-ui Component affected by issue or PR comp-docker-admin-ui Component affected by issue or PR kind-bug Issue or PR is a bug in existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(admin-ui): Use typescript generated SCRIPTS pages

4 participants