Skip to content

Conversation

michelle0927
Copy link
Collaborator

@michelle0927 michelle0927 commented Oct 7, 2024

Resolves #14154
Resolves #14222

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced a new action for creating users in the Nile database.
    • Added a new action for executing custom PostgreSQL queries within the Nile database.
    • Implemented event sources for handling the creation of new users and new tenants.
    • Enhanced user and database management functionalities within the Nile application.
  • Bug Fixes

    • Improved error handling during query execution to ensure database clients are released properly.
  • Chores

    • Updated version number and added dependencies in the package configuration.

Copy link

vercel bot commented Oct 7, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

3 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Ignored (Inspect) Visit Preview Oct 9, 2024 6:43pm
pipedream-docs ⬜️ Ignored (Inspect) Oct 9, 2024 6:43pm
pipedream-docs-redirect-do-not-edit ⬜️ Ignored (Inspect) Oct 9, 2024 6:43pm

Copy link
Contributor

coderabbitai bot commented Oct 7, 2024

Walkthrough

A new module for creating users and executing custom PostgreSQL queries has been added to the Nile database application. The "Create User" module allows for user creation with specified properties, while the "Execute Query" module enables users to run SQL queries and receive results. Additionally, several methods have been introduced to enhance database interactions, including user management and API request handling. The package.json file has been updated to reflect a new version and added dependencies.

Changes

File Path Change Summary
components/nile_database/actions/create-user/create-user.mjs New action "Create User" introduced with metadata and properties for user creation.
components/nile_database/actions/execute-query/execute-query.mjs New action "Execute Query" introduced for executing PostgreSQL queries.
components/nile_database/nile_database.app.mjs Multiple new methods added for user and database interaction, including createUser, listUsers, and _makeRequest.
components/nile_database/package.json Version updated from 0.0.1 to 0.1.0. Added dependencies on @pipedream/platform and pg.
components/nile_database/sources/common/base.mjs New base module introduced for Nile database interaction with properties and methods for resource handling.
components/nile_database/sources/new-tenant-created/new-tenant-created.mjs New source module for emitting events related to new tenant creation.
components/nile_database/sources/new-user-created/new-user-created.mjs New source module for emitting events related to new user creation.

Assessment against linked issues

Objective Addressed Explanation
Create new user
New user added
New tenant created

Possibly related PRs

  • New Components - acymailing #12377: The main PR introduces a new user creation module, which is related to the user management functionalities expanded in this PR, particularly the add-update-user action that also deals with user creation and updates.
  • New Components - okta #12439: This PR includes a new user creation action in the Okta system, which aligns with the user creation functionality in the main PR.
  • Create query-sql-database.mjs #12617: The main PR's user creation functionality may relate to the database query execution capabilities introduced in this PR, as both involve user data handling.
  • New Components - talenthr #14078: The new employee creation action in the TalentHR system is directly related to the user creation functionality in the main PR, as both involve creating new user records in their respective systems.

Suggested labels

ai-assisted, action, trigger / source

Suggested reviewers

  • jcortes

🐰 In the garden where users grow,
A new action to create, oh what a show!
With queries to run and tenants to find,
The Nile database blossoms, one of a kind!
Emitting events, both user and tenant,
In the world of data, our joy is evident! 🌼✨


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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

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

@michelle0927 michelle0927 mentioned this pull request Oct 7, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (1)
components/nile_database/actions/execute-query/execute-query.mjs (1)

1-8: LGTM with a minor suggestion for the description.

The import statement and action metadata look good. The description provides useful information and a link to the documentation.

Consider adding a brief mention of the Nile database in the description for more context. For example:

- description: "Execute a custom PostgreSQL query. See [our docs](https://pipedream.com/docs/databases/working-with-sql) to learn more about working with SQL in Pipedream.",
+ description: "Execute a custom PostgreSQL query on the Nile database. See [our docs](https://pipedream.com/docs/databases/working-with-sql) to learn more about working with SQL in Pipedream.",
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 48c9061 and b173730.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • components/nile_database/actions/execute-query/execute-query.mjs (1 hunks)
  • components/nile_database/nile_database.app.mjs (1 hunks)
  • components/nile_database/package.json (2 hunks)
🧰 Additional context used
🔇 Additional comments (7)
components/nile_database/package.json (3)

3-3: Version bump reflects new features

The version update from 0.0.1 to 0.1.0 appropriately reflects the addition of new features, specifically the Execute Query action mentioned in the PR objectives.


12-14: PublishConfig ensures public access

The 'access' property set to 'public' in the publishConfig section is appropriate for an open-source project like Pipedream. This ensures that the package can be published and accessed publicly.


15-17: New dependency added for PostgreSQL interactions

The addition of the 'pg' package (PostgreSQL client for Node.js) is consistent with the new Execute Query functionality. This dependency will enable PostgreSQL database interactions.

To ensure the 'pg' package is being utilized in the codebase, let's run the following script:

components/nile_database/actions/execute-query/execute-query.mjs (1)

1-28: Consider adding input validation and security measures.

The overall implementation of the "Execute Query" action looks good. However, given that this action allows execution of custom SQL queries, it's important to consider potential security implications.

Consider implementing the following security measures:

  1. Input validation: Add a validation step to ensure that the SQL query doesn't contain potentially harmful operations (e.g., DROP TABLE, TRUNCATE, etc.).

  2. Query limitations: Implement restrictions on the types of queries that can be executed (e.g., only allow SELECT statements).

  3. Resource limits: Add timeouts and result size limits to prevent resource exhaustion.

  4. Logging: Implement comprehensive logging of executed queries for auditing purposes.

Here's a basic example of how you might implement some of these suggestions:

import { parse } from 'pgsql-ast-parser';

// ... existing code ...

async run({ $ }) {
  try {
    // Validate and sanitize the SQL query
    const ast = parse(this.sql);
    if (ast.some(stmt => stmt.type !== 'select')) {
      throw new Error('Only SELECT statements are allowed');
    }

    const args = this.nile.executeQueryAdapter(this.sql);
    
    // Add timeout to query execution
    const timeoutPromise = new Promise((_, reject) => 
      setTimeout(() => reject(new Error('Query execution timed out')), 30000)
    );
    const queryPromise = this.nile.executeQuery(args);
    const data = await Promise.race([queryPromise, timeoutPromise]);

    // Limit result size
    if (data.length > 1000) {
      throw new Error('Query returned too many rows. Please limit your result set.');
    }

    // Log the executed query (consider redacting sensitive information)
    console.log(`Executed query: ${this.sql}`);

    const redactedSQL = this.sql.replace(/\b(password|secret|key)\b\s*=\s*['"]?[^\s'"]+['"]?/gi, '$1=*****');
    $.export("$summary", `Executed query: ${redactedSQL}. Returned ${data.length} ${data.length === 1 ? "row" : "rows"}`);
    return data;
  } catch (error) {
    throw new Error(`Failed to execute query: ${error.message}`);
  }
},

// ... rest of the code ...

Note that this is a basic implementation and you may need to adjust it based on your specific security requirements and the capabilities of the nile object.

To ensure that these security measures are properly implemented across the codebase, you can run the following verification script:

This script will help identify potential security issues and ensure that the suggested measures are consistently applied across the codebase.

components/nile_database/nile_database.app.mjs (3)

81-84: Verify compatibility of the nullish coalescing assignment (??=) operator

In the getSchema() method, the nullish coalescing assignment operator (??=) is used:

acc[row.tableName] ??= {
  metadata: {},
  schema: {},
};

This operator is supported in Node.js 15 and above. If your runtime environment includes older versions of Node.js, this could cause a syntax error.

If compatibility with older Node.js versions is required, consider using an alternative:

if (!acc[row.tableName]) {
  acc[row.tableName] = {
    metadata: {},
    schema: {},
  };
}

65-89: Ensure the SQL query in getSchema retrieves the intended schemas

In the getSchema() method, the SQL query filters out certain schemas:

WHERE table_schema NOT IN ('pg_catalog', 'information_schema', 'users', 'auth')
  • Confirm that excluding the 'users' and 'auth' schemas is intentional. These schemas might contain important tables for authentication and user management that you may want to include.

  • Ensure that all necessary schemas are included. If there are custom schemas or additional system schemas that should be excluded or included, adjust the WHERE clause accordingly.


1-92: Overall, the code changes enhance database interaction capabilities

The addition of methods for configuration, query execution, and schema retrieval significantly improves the application's functionality. Proper exception handling and the use of async/await ensure robust database operations.

luancazarine
luancazarine previously approved these changes Oct 7, 2024
Copy link
Collaborator

@luancazarine luancazarine left a comment

Choose a reason for hiding this comment

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

Hi @michelle0927, LGTM! Ready for QA!

@michelle0927 michelle0927 changed the title Nile Database: Execute Query action New Components - nile_database Oct 9, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Outside diff range and nitpick comments (9)
components/nile_database/sources/new-user-created/new-user-created.mjs (3)

3-10: LGTM: Well-structured component definition. Consider adding documentation.

The exported object is well-structured and includes all necessary metadata for a Pipedream source component. The use of spreading from the common object promotes code reuse.

Consider adding a brief comment above the export to describe the purpose of this component, which could help with maintainability.


13-15: LGTM: getResourceFn implementation. Consider error handling.

The getResourceFn method correctly returns the listUsers function from the Nile database context.

Consider adding error handling in case this.nile or this.nile.listUsers is undefined:

getResourceFn() {
  if (!this.nile || typeof this.nile.listUsers !== 'function') {
    throw new Error('Nile database or listUsers function is not properly initialized');
  }
  return this.nile.listUsers;
},

16-22: LGTM: generateMeta implementation. Consider input validation.

The generateMeta method correctly constructs a metadata object from the user data.

Consider adding input validation to ensure the user object has the required properties:

generateMeta(user) {
  if (!user || typeof user !== 'object' || !user.id || !user.created) {
    throw new Error('Invalid user object');
  }
  return {
    id: user.id,
    summary: `New User ID: ${user.id}`,
    ts: Date.parse(user.created),
  };
},
components/nile_database/sources/new-tenant-created/new-tenant-created.mjs (2)

3-10: LGTM: Well-structured component definition.

The main object is correctly defined and extends the common base module. The properties provide clear information about the component. Consider adding more details to the description, such as mentioning the specific use case or any important considerations for users implementing this component.


11-23: LGTM: Well-implemented methods with room for improvement.

The methods are correctly defined and serve their intended purposes. The generateMeta method creates a comprehensive metadata object for each new tenant event.

Consider adding error handling in the getResourceFn method to gracefully handle potential issues with accessing this.nile.listTenants. This could improve the robustness of the component.

Here's a suggested improvement for the getResourceFn method:

getResourceFn() {
  if (!this.nile || typeof this.nile.listTenants !== 'function') {
    throw new Error('Unable to access listTenants function from Nile database context');
  }
  return this.nile.listTenants;
},
components/nile_database/actions/create-user/create-user.mjs (3)

3-8: LGTM: Action metadata is well-defined.

The action metadata is comprehensive and follows a consistent format. The description provides useful context and includes a link to the API documentation, which is helpful for users.

Consider using semantic versioning (e.g., "1.0.0") for future releases to better indicate the nature of changes in the component.


9-39: LGTM: Props are well-defined, but consider enhancing password security.

The props definition is comprehensive and includes all necessary fields for user creation. The use of propDefinitions for workspace and database promotes reusability.

Consider enhancing the security of the password prop:

  1. Add a secret: true property to prevent the password from being displayed in logs or UI.
  2. Implement password strength requirements using a regex pattern or custom validation logic.

Example implementation:

password: {
  type: "string",
  label: "Password",
  description: "Password for the user (must be at least 8 characters long and include a number and a special character)",
  secret: true,
  pattern: "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{8,}$",
},

40-53: LGTM: Run method implementation is correct, but consider adding error handling.

The run method correctly implements the user creation logic using the provided nile.createUser method. The use of $.export for the summary message is good for providing user feedback.

Consider adding error handling to improve robustness:

async run({ $ }) {
  try {
    const response = await this.nile.createUser({
      $,
      workspace: this.workspace,
      database: this.database,
      data: {
        email: this.email,
        password: this.password,
        preferredName: this.preferredName,
      },
    });
    $.export("$summary", `Successfully created user with ID: ${response.id}`);
    return response;
  } catch (error) {
    $.export("$summary", `Failed to create user: ${error.message}`);
    throw error;
  }
}

This will provide more informative error messages and ensure that errors are properly propagated.

components/nile_database/actions/execute-query/execute-query.mjs (1)

9-42: Props are well-defined, but consider adding query validation.

The props are correctly structured and include all necessary parameters for database connection and query execution. The use of propDefinition for the 'database' prop is a good practice.

However, to enhance security, consider adding validation or sanitization for the 'query' prop to prevent potential SQL injection attacks.

You could add a custom validation function to the 'query' prop:

query: {
  type: "string",
  label: "Query",
  description: "The PostgreSQL query to execute",
  validate: (value) => {
    // Basic validation example - adjust as needed
    if (!/^SELECT/i.test(value)) {
      throw new Error("Only SELECT queries are allowed for security reasons.");
    }
  },
},
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b173730 and 5127e5f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • components/nile_database/actions/create-user/create-user.mjs (1 hunks)
  • components/nile_database/actions/execute-query/execute-query.mjs (1 hunks)
  • components/nile_database/nile_database.app.mjs (1 hunks)
  • components/nile_database/package.json (2 hunks)
  • components/nile_database/sources/common/base.mjs (1 hunks)
  • components/nile_database/sources/new-tenant-created/new-tenant-created.mjs (1 hunks)
  • components/nile_database/sources/new-user-created/new-user-created.mjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/nile_database/package.json
🧰 Additional context used
🔇 Additional comments (8)
components/nile_database/sources/new-user-created/new-user-created.mjs (1)

1-1: LGTM: Import statement is appropriate.

The import of the common base module is correct and follows good practices for code reuse.

components/nile_database/sources/new-tenant-created/new-tenant-created.mjs (2)

1-1: LGTM: Import statement is correct and follows best practices.

The import of the common base module promotes code reuse and maintainability.


1-24: Overall assessment: Well-implemented component with minor improvement opportunities.

This new component for handling new tenant creation events in Nile Database is well-structured and aligns with the PR objectives. It extends the common base module effectively and implements the necessary methods for event handling.

Key strengths:

  1. Clear and concise component definition
  2. Proper use of the common base module
  3. Well-implemented methods for resource access and metadata generation

Suggestions for improvement:

  1. Consider adding more details to the component description
  2. Implement error handling in the getResourceFn method

The component is ready for use, and these minor enhancements would further improve its robustness and usability.

components/nile_database/actions/create-user/create-user.mjs (2)

1-1: LGTM: Import statement is correct.

The import statement correctly references the nile_database.app.mjs file using a relative path. The use of the .mjs extension is appropriate for ECMAScript modules.


1-54: Overall assessment: Well-implemented "Create User" action with minor improvement opportunities.

The "Create User" action for the Nile database is well-structured and correctly implemented. It provides a clear interface for creating users with necessary properties and integrates well with the Nile database app.

Key strengths:

  1. Clear and descriptive metadata
  2. Well-defined props with reusable definitions
  3. Straightforward implementation of the run method

Suggested improvements:

  1. Enhance password security measures
  2. Implement error handling in the run method
  3. Consider using semantic versioning for future releases

These enhancements will further improve the robustness and security of the component.

components/nile_database/actions/execute-query/execute-query.mjs (3)

1-8: LGTM: Import and action metadata are well-defined.

The import statement and action metadata are correctly structured. The description accurately reflects the purpose of the action, and the version number is appropriate for a new component.


43-45: LGTM: Run method structure is correct.

The run method is properly defined as an async function, and the config object is correctly constructed using the prop values. The use of destructuring for the $ object follows Pipedream conventions.


1-57: Overall, the implementation is solid with room for enhancement.

The "Execute Query" action for the Nile database is well-structured and implements the necessary functionality. The code is clean, readable, and follows Pipedream conventions.

Key strengths:

  1. Clear and concise action metadata
  2. Well-defined props covering all necessary parameters
  3. Correct use of async/await for database operations

Suggested improvements:

  1. Implement query validation to enhance security
  2. Add comprehensive error handling
  3. Improve the summary export with more details
  4. Implement basic validation of the returned data

By addressing these points, you'll significantly enhance the robustness and security of this action. Great job on the initial implementation!

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

🧹 Outside diff range and nitpick comments (1)
components/nile_database/nile_database.app.mjs (1)

7-26: LGTM with suggestion: Consider adding error handling to propDefinitions options.

The propDefinitions for "workspace" and "database" are well-structured with clear labels and descriptions. The use of async options to fetch values dynamically is a good practice. However, consider adding error handling to the async options to gracefully handle potential API failures.

Example for the workspace option:

async options() {
  try {
    const { workspaces } = await this.getAuthenticatedUser();
    return workspaces?.map(({ slug }) => slug) || [];
  } catch (error) {
    console.error("Error fetching workspaces:", error);
    return [];
  }
},

Apply similar error handling to the database option as well.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 5127e5f and 9fb079c.

📒 Files selected for processing (2)
  • components/nile_database/actions/execute-query/execute-query.mjs (1 hunks)
  • components/nile_database/nile_database.app.mjs (1 hunks)
🧰 Additional context used
🔇 Additional comments (8)
components/nile_database/actions/execute-query/execute-query.mjs (4)

1-8: LGTM: Import and action metadata look good.

The import statement and action metadata are well-structured and provide clear information about the component. The version "0.0.1" is appropriate for a new component.


9-38: LGTM: Props definition is comprehensive and well-documented.

The props cover all necessary inputs for executing a query, with clear and informative descriptions. Previous review comments about the typo in the SQL query label and the eslint-disable comment have been addressed.


39-49: LGTM: Run method initialization is well-structured.

The async run method is correctly implemented, creating a comprehensive config object with user credentials and dynamically retrieved connection details. This approach provides flexibility and follows good practices for database operations.


1-56: Overall, the implementation is solid with room for minor improvements.

The "Execute Query" action is well-structured and covers the basic functionality required. It follows the expected format for a Pipedream action and includes all necessary parts. The suggested improvements in error handling, summary export, and data validation will enhance its robustness and user-friendliness.

Great job on implementing this new component! Once the suggested improvements are incorporated, this will be a valuable addition to the Nile database integration.

components/nile_database/nile_database.app.mjs (4)

1-6: LGTM: Imports and app declaration are correct.

The imports for axios and pg are appropriate for the app's functionality, and the app declaration follows the expected format.


127-134: LGTM: Proper handling of database client in executeQuery.

The executeQuery method correctly uses a try-finally block to ensure the client is released, even if an error occurs. This is a good practice for managing database connections.


1-137: Overall assessment: Good implementation with room for improvements.

The nile_database.app.mjs file provides a solid foundation for interacting with the Nile database API and executing queries. The code is generally well-structured and follows consistent patterns. However, there are several areas where improvements can be made:

  1. Error handling in propDefinitions
  2. Correct usage of axios in the app context
  3. More robust URL parsing
  4. Reduction of code duplication in API methods
  5. Implementation of connection pooling for better database performance

Addressing these points will enhance the reliability, efficiency, and maintainability of the application. Great work overall, and these suggested improvements will further strengthen the implementation.


41-60: ⚠️ Potential issue

Fix: Correct the use of $ in _makeRequest.

In an app file, the $ context is not available. Replace axios($, ...) with this._axios(...) to use the built-in axios method for app files.

 async _makeRequest({
-  $ = this,
   workspace,
   database,
   url,
   path,
   ...opts
 }) {
-  return axios($, {
+  return this._axios({
     url: url || `${await this._getBaseUrl({
       workspace,
       database,
-      $,
     })}${path}`,
     headers: {
       Authorization: `Bearer ${this.$auth.oauth_access_token}`,
     },
     ...opts,
   });
 },

This change ensures that HTTP requests are correctly handled within the app file's context.

Likely invalid or redundant comment.

Copy link
Collaborator

@jcortes jcortes left a comment

Choose a reason for hiding this comment

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

Hi @michelle0927 lgtm! Ready for QA!

@michelle0927 michelle0927 merged commit d72e32f into master Oct 10, 2024
12 checks passed
@michelle0927 michelle0927 deleted the issue-14154 branch October 10, 2024 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Nile - New Components Nile
3 participants