Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: select widget lazy loading #38867

Merged
merged 61 commits into from
Feb 13, 2025
Merged

Conversation

ayushpahwa
Copy link
Contributor

@ayushpahwa ayushpahwa commented Jan 28, 2025

Description

This PR adds capability of server side pagination to the dropdown form component. There is another PR in works to add server side search. To ensure both grouping and pagination work correctly, the dropdown control component is refactored by adding memoization and fixing some rendering issues.

Fixes #38079

Automation

/ok-to-test tags="@tag.All"

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/13306719132
Commit: 01f4649
Cypress dashboard.
Tags: @tag.All
Spec:


Thu, 13 Feb 2025 12:58:12 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • New Features

    • Enabled dynamic pagination for form options, allowing users to load additional choices smoothly.
    • Enhanced dropdown controls for both single and multi-select modes with improved responsiveness and clearer grouping.
    • Improved form evaluation processes for a more seamless and performant user experience.
    • Introduced new functionality for fetching paginated dynamic values, enhancing the overall data handling experience.
    • Added new function to retrieve conditional output based on form configuration.
  • Bug Fixes

    • Improved error handling and logging for dynamic value fetching processes.

Copy link
Contributor

coderabbitai bot commented Jan 28, 2025

Walkthrough

This update enhances the form evaluation process by introducing support for pagination of dynamic values. It adds new action types and corresponding action creator functions, integrates new saga functions to handle paginated dynamic value fetching, and updates both the reducer and DropDownControl component to correctly process and display these dynamic values. Additionally, new tests and type refinements are provided to support the updated functionality.

Changes

File(s) Change Summary
app/client/.../actions/evaluationActions.ts
app/client/.../ce/constants/ReduxActionConstants.tsx
Added new type imports and a function fetchFormDynamicValNextPage in evaluationActions.ts; introduced two new UQI form action types (FETCH_FORM_DYNAMIC_VAL_NEXT_PAGE_INIT and FETCH_FORM_DYNAMIC_VAL_NEXT_PAGE_SUCCESS) in ReduxActionConstants.tsx.
app/client/.../ce/sagas/index.tsx
app/client/.../sagas/FormEvaluationSaga.ts
Added new saga functions: fetchPaginatedDynamicValuesSaga to handle paginated dynamic values and formEvaluationSagas to integrate these into the saga list; modified the existing fetchDynamicValueSaga for streamlined dynamic value evaluations and error handling.
app/client/.../components/formControls/DropDownControl.tsx
app/client/.../components/formControls/DropDownControl.test.tsx
Enhanced DropDownControl component with memoized grouping and pagination features; updated component props to include pagination parameters; added helper methods (onSelectOptions, onRemoveOptions, and clearAllOptions) and updated tests for single/multi select and placeholder behavior.
app/client/.../reducers/evaluationReducers/triggerReducer.ts
app/client/.../selectors/formSelectors.ts
Added new reducer case for FETCH_FORM_DYNAMIC_VAL_NEXT_PAGE_SUCCESS with duplication checks and state updates in triggerReducer.ts; introduced new interface TriggerActionNextPagePayload and a selector getFormConfigConditionalOutput in formSelectors.ts to retrieve conditional outputs.

Sequence Diagram(s)

sequenceDiagram
    participant UI as UI Component
    participant AC as Action Creator
    participant Saga as Dynamic Values Saga
    participant API as API Service
    participant Reducer as Trigger Reducer

    UI->>AC: fetchFormDynamicValNextPage(payload)
    AC->>Saga: Dispatch FETCH_FORM_DYNAMIC_VAL_NEXT_PAGE_INIT
    Saga->>API: Call fetchDynamicValueSaga(payload)
    API-->>Saga: Return dynamic values
    Saga->>Reducer: Dispatch FETCH_FORM_DYNAMIC_VAL_NEXT_PAGE_SUCCESS
    Reducer-->>UI: Update state with concatenated dynamic values
Loading

Possibly related PRs

  • chore: merge updateActionData with an evaluation #38793: The changes in the main PR are related to the addition of new action types and functions for handling dynamic values, which directly connects to the modifications in the retrieved PR that also involve enhancements to evaluation logic and action data handling.
  • fix: adjust spacing for filter/sort/pagination form controls #37221: The changes in the main PR, specifically the addition of the fetchFormDynamicValNextPage function and the new action type FETCH_FORM_DYNAMIC_VAL_NEXT_PAGE_INIT, are directly related to the pagination functionality introduced in the retrieved PR, which also focuses on pagination controls.
  • chore: Create query selector #37018: The changes in the main PR, specifically the addition of the fetchFormDynamicValNextPage function and the new action type FETCH_FORM_DYNAMIC_VAL_NEXT_PAGE_INIT, are related to the modifications in the retrieved PR, which also introduces a new action type and updates the handling of dynamic values.

Suggested labels

Widgets Product, Query Forms, Widgets & Accelerators Pod, Query & JS Pod, Low, Production

Suggested reviewers

  • AmanAgarwal041
  • ApekshaBhosale
  • rajatagrawal
  • jsartisan

Poem

Code flows like a gentle stream,
Pagination and sagas join the team,
Dropdowns now group and glide with ease,
New actions spark with dynamic keys,
Our tests ensure the logic gleams,
A whimsical patch for devs to please!
🚀 Happy coding!


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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@ayushpahwa ayushpahwa changed the base branch from release to feat/multi-select-widget-grouping January 28, 2025 08:39
@github-actions github-actions bot added the Enhancement New feature or request label Jan 28, 2025
@github-actions github-actions bot added Task A simple Todo Workflows Pod Issues that the workflows team owns Workflows Product Issues related to the workflows product labels Feb 12, 2025
@ayushpahwa ayushpahwa marked this pull request as ready for review February 12, 2025 19:47
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

🧹 Nitpick comments (2)
app/client/src/components/formControls/DropDownControl.tsx (1)

490-496: Consider using optional chaining here.

For consistency, you could simplify the code by using optional chaining when destructuring dynamicFetchedValues. However, your existing null checks and fallback assignments are functionally correct.

- const { data } = dynamicFetchedValues;
- if (data && data.content && data.startIndex != null) {
+ const { data } = dynamicFetchedValues ?? {};
+ if (data?.content && data?.startIndex != null) {
    // ...
  }
🧰 Tools
🪛 Biome (1.9.4)

[error] 496-496: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

app/client/src/actions/evaluationActions.ts (1)

134-148: Consider improving the action creator implementation.

  1. The function returns undefined when payload is not provided, which could lead to runtime issues.
  2. The payload type could be extracted to a separate interface for better reusability.

Consider this implementation:

+interface FetchFormDynamicValNextPagePayload {
+  value: ConditionalOutput;
+  dynamicFetchedValues: DynamicValues;
+  actionId: string;
+  datasourceId: string;
+  pluginId: string;
+  identifier: string;
+}

-export const fetchFormDynamicValNextPage = (payload?: {
-  value: ConditionalOutput;
-  dynamicFetchedValues: DynamicValues;
-  actionId: string;
-  datasourceId: string;
-  pluginId: string;
-  identifier: string;
-}) => {
-  if (payload) {
-    return {
-      type: ReduxActionTypes.FETCH_FORM_DYNAMIC_VAL_NEXT_PAGE_INIT,
-      payload,
-    };
-  }
-};
+export const fetchFormDynamicValNextPage = (
+  payload: FetchFormDynamicValNextPagePayload,
+) => ({
+  type: ReduxActionTypes.FETCH_FORM_DYNAMIC_VAL_NEXT_PAGE_INIT,
+  payload,
+});
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between be3809f and 9c4297a.

📒 Files selected for processing (8)
  • app/client/src/actions/evaluationActions.ts (2 hunks)
  • app/client/src/ce/constants/ReduxActionConstants.tsx (1 hunks)
  • app/client/src/ce/sagas/index.tsx (2 hunks)
  • app/client/src/components/formControls/DropDownControl.test.tsx (7 hunks)
  • app/client/src/components/formControls/DropDownControl.tsx (6 hunks)
  • app/client/src/reducers/evaluationReducers/triggerReducer.ts (3 hunks)
  • app/client/src/sagas/FormEvaluationSaga.ts (4 hunks)
  • app/client/src/selectors/formSelectors.ts (2 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
app/client/src/reducers/evaluationReducers/triggerReducer.ts

[error] 89-89: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

app/client/src/components/formControls/DropDownControl.tsx

[error] 496-496: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (7)
app/client/src/components/formControls/DropDownControl.tsx (3)

32-106: Well-structured grouping logic.

The buildGroupedOptions function and its memoized counterpart are cleanly implemented with the necessary fallback logic. This structure efficiently handles grouping options while avoiding data mutation.


399-407: Great pagination trigger on scroll.

Your scroll event logic properly checks for pagination needs and triggers the next page fetch. This ensures smooth incremental loading in the dropdown.


556-570: Well-structured action dispatch.

The fetchFormTriggerNextPage dispatcher follows a clear pattern and handles the payload gracefully. No issues found.

app/client/src/reducers/evaluationReducers/triggerReducer.ts (2)

66-104: Robust handling of next-page dynamic values.

The new reducer case effectively prevents duplicate calls and merges incoming content into existing data. Good use of immer for immutability.

🧰 Tools
🪛 Biome (1.9.4)

[error] 89-89: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


88-91: Safe optional chaining usage.

Despite the static analysis notice, your prior null checks ensure this optional chaining doesn't lead to runtime errors. The flow is logically correct here.

🧰 Tools
🪛 Biome (1.9.4)

[error] 89-89: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

app/client/src/ce/sagas/index.tsx (1)

24-26: Addition of formEvaluationSagas looks good.

Including formEvaluationSagas in your saga array extends the form evaluation functionalities seamlessly.

Also applies to: 86-86

app/client/src/ce/constants/ReduxActionConstants.tsx (1)

754-757: LGTM! Well-structured action type constants.

The new action types follow the established naming convention and clearly indicate their purpose for form dynamic value pagination.

@ayushpahwa ayushpahwa added the ok-to-test Required label for CI label Feb 12, 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: 0

♻️ Duplicate comments (1)
app/client/src/sagas/FormEvaluationSaga.ts (1)

174-215: ⚠️ Potential issue

Error handling needs improvement.

The error handling in fetchPaginatedDynamicValuesSaga needs enhancement with proper error propagation and retry mechanism.

The previous review comment about error handling and timeouts is still valid. Please implement the suggested improvements:

  1. Add retry mechanism
  2. Add request timeouts
  3. Dispatch error action on failure
  4. Remove console logging
🧹 Nitpick comments (1)
app/client/src/sagas/FormEvaluationSaga.ts (1)

269-282: Fix typo in TODO comment.

There's a typo in the TODO comment: "TODOD" should be "TODO".

-          // TODOD: Find a better way to pass the workspaceId
+          // TODO: Find a better way to pass the workspaceId
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9c4297a and 78339e9.

📒 Files selected for processing (1)
  • app/client/src/sagas/FormEvaluationSaga.ts (6 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-build / client-build
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (3)
app/client/src/sagas/FormEvaluationSaga.ts (3)

2-10: LGTM! Clean import organization.

The imports are well-organized and the new utility objectKeys is appropriately imported.

Also applies to: 42-42


150-150: LGTM! Improved type safety with objectKeys.

The replacement of Object.keys with objectKeys enhances type safety.


376-383: LGTM! Well-structured saga watcher.

The formEvaluationSagas function is well-structured using all and takeLatest for handling paginated dynamic value fetching.

}
}

/* ---------------------------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

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

this comment is not much useful. 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted, updated!

} from "reducers/evaluationReducers/formEvaluationReducer";

/**
* Interface for grouped dropdown options with label and children
Copy link
Contributor

@jsartisan jsartisan Feb 13, 2025

Choose a reason for hiding this comment

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

All these comments are not that useful. They are bloating the code.
It's pretty obvious this is an interface for dropdown grouped options.
Try removing such comments, you will realize it is still readable.
Using Typescript and using good variable/function name are enough for good documentation part here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted, updated!

* @property {string} label - Display label for the option group
* @property {SelectOptionProps[]} children - Array of options within this group
*/
export interface DropDownGroupedOptionsInterface {
Copy link
Contributor

Choose a reason for hiding this comment

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

Using Interface as suffix in the DropDownGroupedOptionsInterface name does not add any value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted, updated!

Comment on lines +44 to +46
* Groups dropdown options based on provided configuration
* The grouping is only done if the optionGroupConfig is provided
* The default group is "others" if not provided
Copy link
Contributor

@jsartisan jsartisan Feb 13, 2025

Choose a reason for hiding this comment

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

The grouping is only done if the optionGroupConfig is provided The default group is "others" if not provided
Now this is a good comments. This is helping reader know about the special case/infromation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted

* @param {Record<string, DropDownGroupedOptionsInterface>} [optionGroupConfig] - Configuration for grouping options
* @returns {DropDownGroupedOptionsInterface[] | null} Grouped options array or null if no grouping needed
*/
function buildGroupedOptions(
Copy link
Contributor

Choose a reason for hiding this comment

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

isn't this file doing too much work. I would have extracted this util to a utils file. I think it's fine for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I thought of taking it out but I felt the context switching might be too high.


/**
* Main dropdown control component supporting single/multi select functionality
* @class DropDownControl
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment about @class and @extends does not add any value.
From the one look, i can tell it's a class that extends another class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted, updated!

* If multi select is not enabled, we just set the value to an empty string
* @param {string | undefined} value - The value to remove
*/
function onRemoveOptions(value: string | undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

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

the valuename is vague. It could be optionToRemove. it's help in readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted, updated!

* Renders the dropdown field component
* @param {Object} props - Component props
* @returns {JSX.Element} Rendered dropdown component
*/
function renderDropdown(
Copy link
Contributor

@jsartisan jsartisan Feb 13, 2025

Choose a reason for hiding this comment

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

if a function is too long, a high level comment would really help the reader about what's happeng and what are the special case the function is handling. otherwise the reader will have to read each line one by one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted, updated!

Copy link
Contributor

@jsartisan jsartisan left a comment

Choose a reason for hiding this comment

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

Mostly the code is okay but the way we write comments can be improved. The comments are needed for things that aren't obvious.

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

🧹 Nitpick comments (5)
app/client/src/components/formControls/DropDownControl.tsx (5)

32-35: Consider renaming the interface.

The Interface suffix in the name is redundant. Consider renaming to just DropDownGroupedOption.

-export interface DropDownGroupedOptions {
+export interface DropDownGroupedOption {
   label: string;
   children: SelectOptionProps[];
 }

120-127: Extract repeated pagination payload type.

The pagination payload type is repeated in multiple places. Consider extracting it to a shared type to improve maintainability.

+type PaginationPayload = {
+  value: ConditionalOutput;
+  dynamicFetchedValues: DynamicValues;
+  actionId: string;
+  datasourceId: string;
+  pluginId: string;
+  identifier: string;
+};

 export interface DropDownControlProps extends ControlProps {
   // ...other props
-  paginationPayload?: {
-    value: ConditionalOutput;
-    dynamicFetchedValues: DynamicValues;
-    actionId: string;
-    datasourceId: string;
-    pluginId: string;
-    identifier: string;
-  };
+  paginationPayload?: PaginationPayload;
 }

Also applies to: 136-143, 457-464


149-174: Simplify dependency change detection.

The nested conditions make the code harder to follow. Consider using early returns and flattening the conditions.

 componentDidUpdate(prevProps: Props) {
-  if (this.props.fetchOptionsConditionally && this.props.isMultiSelect) {
-    const dependencies = matchExact(
-      MATCH_ACTION_CONFIG_PROPERTY,
-      this.props.conditionals?.fetchDynamicValues?.condition,
-    );
-    let hasDependenciesChanged = false;
-
-    if (dependencies?.length) {
-      dependencies.forEach((depPath) => {
-        const prevValue = get(prevProps.formValues, depPath);
-        const currValue = get(this.props.formValues, depPath);
-
-        if (prevValue !== currValue) hasDependenciesChanged = true;
-      });
-    }
-
-    if (hasDependenciesChanged) {
-      this.props.updateConfigPropertyValue(
-        this.props.formName,
-        this.props.configProperty,
-        [],
-      );
-    }
-  }
+  if (!this.props.fetchOptionsConditionally || !this.props.isMultiSelect) return;
+
+  const dependencies = matchExact(
+    MATCH_ACTION_CONFIG_PROPERTY,
+    this.props.conditionals?.fetchDynamicValues?.condition,
+  );
+
+  if (!dependencies?.length) return;
+
+  const hasDependenciesChanged = dependencies.some(
+    (depPath) =>
+      get(prevProps.formValues, depPath) !== get(this.props.formValues, depPath)
+  );
+
+  if (hasDependenciesChanged) {
+    this.props.updateConfigPropertyValue(
+      this.props.formName,
+      this.props.configProperty,
+      [],
+    );
+  }

482-482: Use optional chaining for safer access.

Consider using optional chaining to safely access nested properties.

-if (data && data.content && data.startIndex != null) {
+if (data?.content && data?.startIndex != null) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 482-482: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


393-401: Consider debouncing the scroll handler.

The scroll handler might fire too frequently. Consider debouncing it to improve performance.

+import { debounce } from "lodash";

-function handlePopupScroll(e: React.UIEvent<HTMLDivElement>) {
+const handlePopupScroll = debounce((e: React.UIEvent<HTMLDivElement>) => {
   if (!props.nextPageNeeded || !props.paginationPayload) return;

   const target = e.currentTarget;

   if (target.scrollHeight - target.scrollTop === target.clientHeight) {
     props.fetchFormTriggerNextPage(props.paginationPayload);
   }
-}
+}, 150);
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 78339e9 and 01f4649.

📒 Files selected for processing (1)
  • app/client/src/components/formControls/DropDownControl.tsx (7 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
app/client/src/components/formControls/DropDownControl.tsx

[error] 482-482: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-build / client-build
  • GitHub Check: client-prettier / prettier-check

Comment on lines +527 to 530
} catch (err) {
// eslint-disable-next-line no-console
console.error(e);
} finally {
return { isLoading, options, formValues };
console.error(err);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve error handling.

The catch block only logs to console. Consider proper error handling and typing.

-} catch (err) {
+} catch (err: unknown) {
   // eslint-disable-next-line no-console
-  console.error(err);
+  console.error('Failed to process dropdown options:', err instanceof Error ? err.message : err);
+  // Consider showing an error state in the UI
+  isLoading = false;
+  options = [];
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (err) {
// eslint-disable-next-line no-console
console.error(e);
} finally {
return { isLoading, options, formValues };
console.error(err);
}
} catch (err: unknown) {
// eslint-disable-next-line no-console
console.error('Failed to process dropdown options:', err instanceof Error ? err.message : err);
// Consider showing an error state in the UI
isLoading = false;
options = [];
}

@ayushpahwa
Copy link
Contributor Author

@jsartisan thanks for the thorough review. I was trying out AI to make file more readable. I'll be more careful around it now. I have updated the comments, please do take a look again. Thanks!

@ayushpahwa ayushpahwa requested a review from jsartisan February 13, 2025 11:34
@ayushpahwa ayushpahwa merged commit fdf7793 into release Feb 13, 2025
85 checks passed
@ayushpahwa ayushpahwa deleted the feat/multi-select-widget-lazy-load branch February 13, 2025 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Anvil Pod Issue related to Anvil project Enhancement New feature or request Frontend This label marks the issue or pull request to reference client code ok-to-test Required label for CI Stale Task A simple Todo Workflows Pod Issues that the workflows team owns Workflows Product Issues related to the workflows product
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update ADS Select
2 participants