enhance field Validations with max text limits#3744
Conversation
…list page, and role assignment functionality - Implemented `getUsers` method in `userService` to fetch users with optional email filter. - Defined `GetUsersResponse` type in `api.ts` for user data structure. - Created `UserDetailPage` component for displaying individual user details and managing roles. - Developed `UserManagementPage` component for listing users with search and pagination, including role update functionality. - Added centralized validation limits in `validation-limits.ts` for consistent input length management across the application.
…add StatsPieChart component
…ious components - Updated button components to use 'loading' prop instead of 'disabled' for better user experience during async operations. - Added 'isValidating' state to buttons in ClientsAdminPage, EmailConfigContent, OrganizationRequestsPage, RoleDetailContent, and SecurityPageContent for improved feedback during data fetching. - Cleaned up code formatting for better readability in multiple files, including user management and role assignment components. - Removed unnecessary comments and improved import statements for consistency.
|
Warning Review limit reached
Next review available in: 22 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughThis PR introduces a centralized ChangesValidation limits and form constraints
User management rework
Loading states, tooltips, and minor fixes
Estimated code review effort: 4 (Complex) | ~75 minutes Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
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. Comment |
|
New azure analytics_platform changes available for preview here |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
src/platform/src/shared/lib/validators.ts (1)
92-109: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAlign the set-password bounds with the shared password limits
setPasswordSchemastill hardcodes.min(6, ...)while the other password schemas usePASSWORD_MIN(8), so this flow accepts a weaker password than the rest. The helper text insrc/platform/src/shared/components/auth/SetPasswordPromptDialog.tsxis also stale: it says “Use 6 to 30 characters...”, but the field now allows up toPASSWORD_MAX(128).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/src/shared/lib/validators.ts` around lines 92 - 109, Update setPasswordSchema in validators.ts to use the shared PASSWORD_MIN constant instead of hardcoding 6, and keep PASSWORD_MAX as the upper bound so it matches the other password validators. Also update the helper text in SetPasswordPromptDialog to reflect the shared limits (PASSWORD_MIN to PASSWORD_MAX) instead of the stale “6 to 30 characters” copy. Ensure the password and confirmPassword validation messaging stays consistent with the shared auth schema.src/platform/src/app/(dashboard)/system/security/page.tsx (1)
964-973: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRefresh button loading state won't reflect actual refreshes.
blockedLoading/flaggedLoadingcome fromuseSWR'sisLoading, which is onlytrueduring the initial fetch (no cached data yet). Once data has loaded, clicking "Refresh" triggersmutate()/revalidation butisLoadingstaysfalse, so the button'sloadingprop never activates on manual refresh — no spinner feedback for the user.Other files touched in this PR (
email-configs/page.tsx,org-requests/page.tsx) correctly destructureisValidatingfrom the SWR result and wire that into the refresh button instead. This file should do the same for consistency and correct UX feedback.🔄 Suggested fix
const { data: blockedAsns, error: blockedError, isLoading: blockedLoading, + isValidating: blockedValidating, mutate: mutateBlocked, } = useSWR('system/security/blocked-asns', fetchAllBlockedAsns, { revalidateOnFocus: false, shouldRetryOnError: false, }); const { data: flaggedTokens, error: flaggedError, isLoading: flaggedLoading, + isValidating: flaggedValidating, mutate: mutateFlagged, } = useSWR('system/security/flagged-tokens', fetchAllFlaggedTokens, { revalidateOnFocus: false, shouldRetryOnError: false, }); ... onClick={handleRefreshBlocked} - loading={blockedLoading} + loading={blockedValidating} ... onClick={handleRefreshFlagged} - loading={flaggedLoading} + loading={flaggedValidating}Also applies to: 1015-1024, 501-519
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/src/app/`(dashboard)/system/security/page.tsx around lines 964 - 973, The refresh buttons in the security page are wired to SWR’s isLoading state, which only covers the initial fetch and won’t show loading during manual revalidation. Update the relevant useSWR destructuring in the security page to use isValidating instead of isLoading for the blocked and flagged data hooks, and pass that value into the Refresh button loading prop used by handleRefreshBlocked and the flagged refresh handler so the spinner reflects actual refreshes. Keep the change consistent with the patterns already used in email-configs/page.tsx and org-requests/page.tsx.src/platform/src/app/(dashboard)/system/roles-permissions/[roleId]/page.tsx (1)
38-50: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRefresh should use
isValidating, notisLoading.
useRoleById()andusePermissions()already return SWR state, so the Refresh button can readisValidatingfrom each hook.isLoadingis only true for the first fetch, and this component returns early during that phase, so this spinner won’t reflect revalidation afterhandleRefresh()runs.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/src/app/`(dashboard)/system/roles-permissions/[roleId]/page.tsx around lines 38 - 50, The Refresh button state is tied to initial loading instead of SWR revalidation, so it won’t show while `handleRefresh()` is running. Update the `useRoleById` and `usePermissions` usage in the roles permissions page to read `isValidating` from each hook instead of `isLoading`, and use those flags in the refresh/spinner logic so the UI reflects background revalidation correctly.src/platform/src/app/(dashboard)/system/surveys/[surveyId]/page.tsx (1)
290-330: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUse
isValidatingfor refresh feedbackisLoadingonly tracks the first SWR fetch, so the Refresh button atsrc/platform/src/app/(dashboard)/system/surveys/[surveyId]/page.tsx:634-641and the responses table refresh affordance lower in the file won’t spin onmutate()revalidations. Switch those indicators toisValidating(or a dedicatedisRefreshingflag).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/src/app/`(dashboard)/system/surveys/[surveyId]/page.tsx around lines 290 - 330, The refresh indicators for the survey page are tied to the initial fetch state instead of revalidation state, so they won’t reflect `mutate()` refreshes. Update the `useSWR` hooks in `page.tsx` for `survey`, `stats`, and `responses` to use `isValidating` (or derive a separate `isRefreshing` flag) and wire the Refresh button and responses table affordance to those values so they spin during revalidation.
🧹 Nitpick comments (7)
src/platform/src/shared/components/BulkRoleAssignmentDialog.tsx (1)
34-259: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffConsider extracting the role-combobox logic into a shared hook.
The search/highlight/keyboard-nav state machine here (roleSearch, filteredRoles, highlightedIndex, click-outside, scroll-into-view) is duplicated almost verbatim in
team-members/[memberId]/page.tsx. Not a blocker for this maxLength change, but worth consolidating into a shareduseRoleComboboxhook next time either file is touched.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/src/shared/components/BulkRoleAssignmentDialog.tsx` around lines 34 - 259, Extract the duplicated role combobox state and behavior from BulkRoleAssignmentDialog into a shared useRoleCombobox hook, since the same search, filtering, highlight, keyboard navigation, click-outside, and scroll-into-view logic also exists in team-members/[memberId]/page.tsx. Keep the dialog component focused on rendering by moving roleSearch, filteredRoles, highlightedIndex, dropdown open/close handling, and selection handlers into the new hook, then reuse it in both places.src/platform/src/shared/lib/validators.ts (2)
111-146: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
profileSchema.countrystill has no max length, unlikeorganizationRequestSchema.countrywhich now usesCOUNTRY_MAXin this same diff. Minor inconsistency, worth aligning for completeness.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/src/shared/lib/validators.ts` around lines 111 - 146, The profileSchema country field is missing the same max-length validation used elsewhere, so align it with organizationRequestSchema by applying COUNTRY_MAX to the country validator in profileSchema. Update the country field in validators.ts to include a max constraint alongside the existing required check, matching the pattern used by the other schema fields in this file.
27-33: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
loginSchema.emailhas no upper bound.
registerSchemaandforgotPwdSchemaboth cap email length withEMAIL_MAX, butloginSchemaonly capspassword. For consistency (and to avoid unbounded strings hitting the auth endpoint), consider adding the sameEMAIL_MAXcap here.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/src/shared/lib/validators.ts` around lines 27 - 33, The loginSchema email field is missing the same EMAIL_MAX length cap used by registerSchema and forgotPwdSchema. Update loginSchema in validators.ts so the email validator also enforces the shared maximum length, matching the other auth schemas and keeping the constraint consistent. Use the existing EMAIL_MAX symbol and keep the current required/email format checks intact.src/platform/src/modules/user-profile/components/ProfileForm.tsx (1)
28-33: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueAdd a client-side length cap to
PhoneNumberInput.ProfileForm.tsxwiresmaxLengthfor the other text fields, but the phone field can’t receive one yet becausePhoneNumberInputPropsdoesn’t expose it. If this field should mirror the rest of the form, forwardPHONE_MAXthrough the wrapper.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/src/modules/user-profile/components/ProfileForm.tsx` around lines 28 - 33, The phone field is missing the same client-side length cap used by the other profile inputs because PhoneNumberInputProps does not accept a maxLength value. Update PhoneNumberInput and its props to forward a maxLength prop through to the underlying input, then wire PHONE_MAX from ProfileForm so the phone field mirrors the rest of the form.src/platform/src/modules/themes/components/ThemeManager.tsx (1)
20-20: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSame
HEX_COLOR_MAXwiring asThemeSettings.tsx.Nice, consistent limit applied here too. Worth noting the custom-color picker markup (input + Apply button block) is now duplicated verbatim between this file and
ThemeSettings.tsx— a sharedHexColorInputcomponent could de-dupe both, but that's pre-existing structure and out of scope for this validation-limits pass.Also applies to: 217-217
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/src/modules/themes/components/ThemeManager.tsx` at line 20, ThemeManager.tsx should use the shared HEX_COLOR_MAX limit the same way ThemeSettings.tsx does, so keep the import from shared/lib/validation-limits and wire that constant into the custom color validation in ThemeManager’s color handling logic (the ThemeManager component and its custom-color picker handlers) instead of any local hardcoded limit. Make sure the same shared limit is used consistently wherever hex color length is validated in this file.src/platform/src/shared/hooks/useAdmin.ts (1)
242-252: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winNo cancellation when
useUsersis re-fired with a changingThe fetcher
() => userService.getUsers(email)doesn't accept/propagate an abort signal, so if this hook backs a search input (re-firing the key on every keystroke), stale in-flight requests can resolve after newer ones, causing UI flicker with outdated results.As per path instructions,
Use AbortController for cohort endpoints and any query that can be re-fired on re-render.🔧 Sketch of abortable fetcher
export const useUsers = (email?: string) => { return useSWR( email ? `admin/users?email=${email}` : 'admin/users', - () => userService.getUsers(email), + (_key, { signal }: { signal?: AbortSignal } = {}) => + userService.getUsers(email, { signal }), { revalidateOnFocus: false, revalidateOnReconnect: false, } ); };(Requires
userService.getUsersto accept and forward anAbortSignalto the underlying HTTP client.)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/src/shared/hooks/useAdmin.ts` around lines 242 - 252, useUsers is refiring on changing email without request cancellation, so stale user list responses can win and flicker the UI. Update useUsers to use an AbortController-backed fetcher and pass the abort signal through to userService.getUsers, then ensure userService.getUsers forwards that signal to the HTTP client so earlier in-flight requests are canceled when the email key changes.Source: Path instructions
src/platform/src/app/(dashboard)/system/users/page.tsx (1)
42-89: 🚀 Performance & Scalability | 🔵 Trivial | 🏗️ Heavy liftSwitch user listing to server-side paging/search
useUsers()still fetches the full user list, and this page filters/paginates it in memory before handing it toServerSideTable. Add page/search params touseUsers/userService.getUsersso the table only loads the current slice.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/src/app/`(dashboard)/system/users/page.tsx around lines 42 - 89, The user list is still being loaded in full and then filtered/paginated in memory in the users page, so update the data flow to use server-side paging/search instead. Extend useUsers and userService.getUsers to accept page, pageSize, and search, then wire those params from the users page so filteredUsers/paginatedUsers logic is replaced by the API response slice before passing data to ServerSideTable.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/platform/src/app/`(dashboard)/system/user-statistics/[id]/page.tsx:
- Around line 1-12: The page component’s props are using the Next 15-style async
contract, but this App Router page should use synchronous params. Update
UserDetailRedirectPageProps so params is { id: string } instead of a Promise,
and adjust UserDetailRedirectPage to read id directly before calling redirect.
Keep the redirect logic intact while aligning the type signature with the
generated page types.
In `@src/platform/src/app/`(dashboard)/system/users/[id]/page.tsx:
- Around line 76-83: Remove the arbitrary fallback in the user role resolution
logic: the primary role should come only from the user’s network or group
associations, not from the global available roles list. Update the useMemo for
primaryRoleId in the page component so it returns an empty value when no
assigned role exists, and make openRoleDialog handle that empty state without
preselecting a role in the Update Role dialog.
- Around line 136-139: The openRoleDialog callback in the user detail page is
not resetting the role search state, so old search text can carry over when the
dialog is reopened. Update openRoleDialog to clear roleSearch before opening the
dialog, matching the behavior in users/page.tsx, and keep the dependency list in
sync with any state setters or values used by the callback.
In `@src/platform/src/app/`(dashboard)/system/users/page.tsx:
- Around line 112-124: The openRoleDialog callback is still defaulting
primaryRoleId to availableRoles[0]?._id, which can prefill the Update Role
dialog with an unrelated role when a user has no assigned role. Update the logic
in openRoleDialog to derive the role only from the user’s existing group/network
role data and otherwise leave it empty, and consider extracting a shared
getPrimaryRoleId(user, availableRoles) helper so the same behavior can be reused
consistently with the user detail page.
In `@src/platform/src/shared/components/charts/components/ui/StatsPieChart.tsx`:
- Around line 39-100: StatsPieChart only treats empty arrays as no data, but it
still renders when all slice values sum to zero. Update the empty-state check in
StatsPieChart so it also returns the “No data available” UI when the total of
data[].value is 0, not just when data is missing or length is 0. Use the
existing StatsPieChart render path and the Pie/ResponsiveContainer block to keep
the fix localized.
In `@src/platform/src/shared/services/userService.ts`:
- Around line 499-514: The getUsers method still fetches the entire users list
in one call, forcing both useUsers consumers to process and slice a full payload
client-side. Update getUsers in userService to accept pagination inputs and
return paging metadata, or introduce a separate aggregation endpoint for the
stats page so it doesn’t rely on the full user dump. Keep the existing
authenticatedClient.get flow but change the response shape and downstream
consumers to use page/limit/meta instead of loading everything at once.
---
Outside diff comments:
In `@src/platform/src/app/`(dashboard)/system/roles-permissions/[roleId]/page.tsx:
- Around line 38-50: The Refresh button state is tied to initial loading instead
of SWR revalidation, so it won’t show while `handleRefresh()` is running. Update
the `useRoleById` and `usePermissions` usage in the roles permissions page to
read `isValidating` from each hook instead of `isLoading`, and use those flags
in the refresh/spinner logic so the UI reflects background revalidation
correctly.
In `@src/platform/src/app/`(dashboard)/system/security/page.tsx:
- Around line 964-973: The refresh buttons in the security page are wired to
SWR’s isLoading state, which only covers the initial fetch and won’t show
loading during manual revalidation. Update the relevant useSWR destructuring in
the security page to use isValidating instead of isLoading for the blocked and
flagged data hooks, and pass that value into the Refresh button loading prop
used by handleRefreshBlocked and the flagged refresh handler so the spinner
reflects actual refreshes. Keep the change consistent with the patterns already
used in email-configs/page.tsx and org-requests/page.tsx.
In `@src/platform/src/app/`(dashboard)/system/surveys/[surveyId]/page.tsx:
- Around line 290-330: The refresh indicators for the survey page are tied to
the initial fetch state instead of revalidation state, so they won’t reflect
`mutate()` refreshes. Update the `useSWR` hooks in `page.tsx` for `survey`,
`stats`, and `responses` to use `isValidating` (or derive a separate
`isRefreshing` flag) and wire the Refresh button and responses table affordance
to those values so they spin during revalidation.
In `@src/platform/src/shared/lib/validators.ts`:
- Around line 92-109: Update setPasswordSchema in validators.ts to use the
shared PASSWORD_MIN constant instead of hardcoding 6, and keep PASSWORD_MAX as
the upper bound so it matches the other password validators. Also update the
helper text in SetPasswordPromptDialog to reflect the shared limits
(PASSWORD_MIN to PASSWORD_MAX) instead of the stale “6 to 30 characters” copy.
Ensure the password and confirmPassword validation messaging stays consistent
with the shared auth schema.
---
Nitpick comments:
In `@src/platform/src/app/`(dashboard)/system/users/page.tsx:
- Around line 42-89: The user list is still being loaded in full and then
filtered/paginated in memory in the users page, so update the data flow to use
server-side paging/search instead. Extend useUsers and userService.getUsers to
accept page, pageSize, and search, then wire those params from the users page so
filteredUsers/paginatedUsers logic is replaced by the API response slice before
passing data to ServerSideTable.
In `@src/platform/src/modules/themes/components/ThemeManager.tsx`:
- Line 20: ThemeManager.tsx should use the shared HEX_COLOR_MAX limit the same
way ThemeSettings.tsx does, so keep the import from shared/lib/validation-limits
and wire that constant into the custom color validation in ThemeManager’s color
handling logic (the ThemeManager component and its custom-color picker handlers)
instead of any local hardcoded limit. Make sure the same shared limit is used
consistently wherever hex color length is validated in this file.
In `@src/platform/src/modules/user-profile/components/ProfileForm.tsx`:
- Around line 28-33: The phone field is missing the same client-side length cap
used by the other profile inputs because PhoneNumberInputProps does not accept a
maxLength value. Update PhoneNumberInput and its props to forward a maxLength
prop through to the underlying input, then wire PHONE_MAX from ProfileForm so
the phone field mirrors the rest of the form.
In `@src/platform/src/shared/components/BulkRoleAssignmentDialog.tsx`:
- Around line 34-259: Extract the duplicated role combobox state and behavior
from BulkRoleAssignmentDialog into a shared useRoleCombobox hook, since the same
search, filtering, highlight, keyboard navigation, click-outside, and
scroll-into-view logic also exists in team-members/[memberId]/page.tsx. Keep the
dialog component focused on rendering by moving roleSearch, filteredRoles,
highlightedIndex, dropdown open/close handling, and selection handlers into the
new hook, then reuse it in both places.
In `@src/platform/src/shared/hooks/useAdmin.ts`:
- Around line 242-252: useUsers is refiring on changing email without request
cancellation, so stale user list responses can win and flicker the UI. Update
useUsers to use an AbortController-backed fetcher and pass the abort signal
through to userService.getUsers, then ensure userService.getUsers forwards that
signal to the HTTP client so earlier in-flight requests are canceled when the
email key changes.
In `@src/platform/src/shared/lib/validators.ts`:
- Around line 111-146: The profileSchema country field is missing the same
max-length validation used elsewhere, so align it with organizationRequestSchema
by applying COUNTRY_MAX to the country validator in profileSchema. Update the
country field in validators.ts to include a max constraint alongside the
existing required check, matching the pattern used by the other schema fields in
this file.
- Around line 27-33: The loginSchema email field is missing the same EMAIL_MAX
length cap used by registerSchema and forgotPwdSchema. Update loginSchema in
validators.ts so the email validator also enforces the shared maximum length,
matching the other auth schemas and keeping the constraint consistent. Use the
existing EMAIL_MAX symbol and keep the current required/email format checks
intact.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2e9e1b22-df88-4e53-9329-30e40be4b386
📒 Files selected for processing (51)
src/platform/docs/SELENIUM_TESTING.mdsrc/platform/src/app/(dashboard)/(individual)/user/(auth)/creation/individual/register/page.tsxsrc/platform/src/app/(dashboard)/(individual)/user/(auth)/forgotPwd/page.tsxsrc/platform/src/app/(dashboard)/(individual)/user/(auth)/forgotPwd/reset/page.tsxsrc/platform/src/app/(dashboard)/(individual)/user/(auth)/login/page.tsxsrc/platform/src/app/(dashboard)/(individual)/user/(pages)/(layout1)/home/page.tsxsrc/platform/src/app/(dashboard)/(organization)/org/[org_slug]/(auth)/login/page.tsxsrc/platform/src/app/(dashboard)/(organization)/org/[org_slug]/(pages)/(layout1)/members/page.tsxsrc/platform/src/app/(dashboard)/(organization)/org/[org_slug]/(pages)/(layout1)/roles/page.tsxsrc/platform/src/app/(dashboard)/request-organization/page.tsxsrc/platform/src/app/(dashboard)/system/clients/[clientId]/page.tsxsrc/platform/src/app/(dashboard)/system/clients/page.tsxsrc/platform/src/app/(dashboard)/system/email-configs/page.tsxsrc/platform/src/app/(dashboard)/system/feedback/[feedbackId]/page.tsxsrc/platform/src/app/(dashboard)/system/feedback/page.tsxsrc/platform/src/app/(dashboard)/system/feedback/webhooks/page.tsxsrc/platform/src/app/(dashboard)/system/org-requests/page.tsxsrc/platform/src/app/(dashboard)/system/roles-permissions/[roleId]/page.tsxsrc/platform/src/app/(dashboard)/system/roles-permissions/components/CreateRoleDialog.tsxsrc/platform/src/app/(dashboard)/system/roles-permissions/page.tsxsrc/platform/src/app/(dashboard)/system/security/page.tsxsrc/platform/src/app/(dashboard)/system/surveys/[surveyId]/page.tsxsrc/platform/src/app/(dashboard)/system/surveys/components/SurveyForm.tsxsrc/platform/src/app/(dashboard)/system/team-members/[memberId]/page.tsxsrc/platform/src/app/(dashboard)/system/team-members/page.tsxsrc/platform/src/app/(dashboard)/system/user-statistics/[id]/page.tsxsrc/platform/src/app/(dashboard)/system/user-statistics/page.tsxsrc/platform/src/app/(dashboard)/system/users/[id]/page.tsxsrc/platform/src/app/(dashboard)/system/users/page.tsxsrc/platform/src/modules/data-visualizer/components/VisualizerChartCard.tsxsrc/platform/src/modules/feedback/components/FeedbackLauncher.tsxsrc/platform/src/modules/location-insights/more-insights.tsxsrc/platform/src/modules/organization/components/GroupDetailsSettings.tsxsrc/platform/src/modules/organization/components/ThemeSettings.tsxsrc/platform/src/modules/themes/components/ThemeManager.tsxsrc/platform/src/modules/user-profile/components/ProfileForm.tsxsrc/platform/src/modules/user-profile/components/SecurityTab.tsxsrc/platform/src/shared/components/BulkRoleAssignmentDialog.tsxsrc/platform/src/shared/components/auth/SetPasswordPromptDialog.tsxsrc/platform/src/shared/components/charts/components/ui/StatsPieChart.tsxsrc/platform/src/shared/components/charts/index.tssrc/platform/src/shared/components/header/components/info-dropdown.tsxsrc/platform/src/shared/components/sidebar/config/index.tssrc/platform/src/shared/components/ui/search-field.tsxsrc/platform/src/shared/components/ui/server-side-table.tsxsrc/platform/src/shared/hooks/useAdmin.tssrc/platform/src/shared/lib/metadata.tssrc/platform/src/shared/lib/validation-limits.tssrc/platform/src/shared/lib/validators.tssrc/platform/src/shared/services/userService.tssrc/platform/src/shared/types/api.ts
…nd character count display
…y UserManagementPage role dialog logic
|
New azure analytics_platform changes available for preview here |
Status of maturity (all need to be checked before merging):
Screenshots (optional)
Summary by CodeRabbit
New Features
Bug Fixes
Documentation