codeant-ai-for-open-source[bot] commented on code in PR #37298:
URL: https://github.com/apache/superset/pull/37298#discussion_r2710427073


##########
superset-frontend/src/SqlLab/components/AppLayout/index.tsx:
##########
@@ -99,47 +139,59 @@ const AppLayout: React.FC = ({ children }) => {
 
   return (
     <StyledContainer>
-      <Splitter
-        css={css`
-          flex: 1;
-        `}
-        lazy
-        onResizeEnd={onSidebarChange}
-        onResize={noop}
-      >
-        <Splitter.Panel
-          collapsible={{
-            start: true,
-            end: true,
-            showCollapsibleIcon: true,
-          }}
-          size={leftWidth}
-          min={SQL_EDITOR_LEFTBAR_WIDTH}
+      <StyledSidebarWrapper>
+        <Layout.Sider
+          collapsed

Review Comment:
   **Suggestion:** Logic bug: `Layout.Sider` is hard-coded to be collapsed 
because the `collapsed` prop is provided without a value (equivalent to true). 
This forces the sidebar to always render in its collapsed state and never 
expand; toggle/resize logic will not make it expand. Make `collapsed` 
controlled by `leftWidth` so the Sider collapses/expands according to state. 
[logic error]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ SQL Lab left sidebar cannot expand (AppLayout component).
   - ⚠️ Database explorer toggle click has no visible effect.
   ```
   </details>
   
   ```suggestion
             collapsed={leftWidth <= SQL_EDITOR_LEFTBAR_COLLAPSED_WIDTH}
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open the SQL Lab UI which mounts AppLayout (component defined in
   superset-frontend/src/SqlLab/components/AppLayout/index.tsx). The AppLayout 
render begins
   at the return block where the sidebar is declared (see Layout.Sider at lines 
143-146 of
   the PR diff).
   
   2. Inspect toggle logic: toggleSidebar useCallback is declared earlier in 
the same file
   (toggleSidebar at line 96 in the PR hunk) and sets leftWidth to 
SQL_EDITOR_LEFTBAR_WIDTH
   when expanding (line 98), and to SQL_EDITOR_LEFTBAR_COLLAPSED_WIDTH when 
collapsing (line
   100).
   
   3. Interact with the collapsed menu: the collapsed Menu is rendered inside 
the Sider
   (StyledMenu at lines 147-151). Clicking the menu item calls toggleSidebar
   (collapsedMenuItems definition at lines 104-115 which uses toggleSidebar).
   
   4. Observe behavior: despite toggleSidebar updating leftWidth, Layout.Sider 
is hard-coded
   with the boolean prop collapsed (see lines 143-146). Because collapsed is 
always true, the
   Sider remains visually collapsed and never expands even after toggleSidebar 
executes —
   reproducing the bug (click collapsed menu item, sidebar does not expand).
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset-frontend/src/SqlLab/components/AppLayout/index.tsx
   **Line:** 144:144
   **Comment:**
        *Logic Error: Logic bug: `Layout.Sider` is hard-coded to be collapsed 
because the `collapsed` prop is provided without a value (equivalent to true). 
This forces the sidebar to always render in its collapsed state and never 
expand; toggle/resize logic will not make it expand. Make `collapsed` 
controlled by `leftWidth` so the Sider collapses/expands according to state.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>



##########
superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx:
##########
@@ -16,12 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { Divider, Flex } from '@superset-ui/core/components';
-import { styled } from '@apache-superset/core/ui';
+import { Divider, EmptyState, Flex } from '@superset-ui/core/components';
+import { css, styled } from '@apache-superset/core/ui';

Review Comment:
   **Suggestion:** The `css` template tag is imported from 
`@apache-superset/core/ui`, but that package may not export a `css` template 
function (the project normally sources the Emotion `css` from 
`@emotion/react`). If `css` is undefined at runtime the `css\`...\`` call will 
throw. Import `css` from `@emotion/react` (and keep `styled` from the current 
UI package) to ensure the template tag exists. [possible bug]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ SqlEditorTopBar fails to render in SQLLab.
   - ❌ DatabaseSelector modal inaccessible from top bar.
   - ⚠️ Primary/secondary menu actions hidden.
   ```
   </details>
   
   ```suggestion
   import { styled } from '@apache-superset/core/ui';
   import { css } from '@emotion/react';
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Build and run the frontend with the PR changes so the SQL editor loads. 
The component
   file to exercise is 
superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx.
   
   2. Navigate to SQLLab so React mounts SqlEditorTopBar (the default export 
from the file
   above). The component renders the JSX block that uses the `css` template tag 
at the Flex
   prop (see the same file where css is used at the block starting around the 
`css\`` usage).
   
   3. At render time the expression css`min-width: 0; overflow: hidden;` (in 
this file) is
   evaluated; if `css` imported from '@apache-superset/core/ui' is undefined, 
React will
   throw TypeError: css is not a function when evaluating the template tag.
   
   4. Observed failure: SQL editor top bar fails to render and a runtime error 
appears in the
   browser console referencing
   superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx (the 
`css\`` usage
   site).
   
      Explanation: the project package `@apache-superset/core/ui` (see
      packages/superset-core/src/ui/theme exports) does not export `css` in 
this codebase;
      keeping `css` imported from there is likely incorrect. Replacing the 
import with `css`
      from '@emotion/react' matches how template tags are provided in other 
code.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx
   **Line:** 20:20
   **Comment:**
        *Possible Bug: The `css` template tag is imported from 
`@apache-superset/core/ui`, but that package may not export a `css` template 
function (the project normally sources the Emotion `css` from 
`@emotion/react`). If `css` is undefined at runtime the `css\`...\`` call will 
throw. Import `css` from `@emotion/react` (and keep `styled` from the current 
UI package) to ensure the template tag exists.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>



##########
superset-frontend/packages/superset-ui-core/src/components/Segmented/types.ts:
##########
@@ -0,0 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import type { SegmentedProps } from 'antd/es/segmented';
+
+export { SegmentedProps };

Review Comment:
   **Suggestion:** Type-only import is being re-exported as a value: `import 
type { SegmentedProps }` followed by `export { SegmentedProps }` attempts to 
export a runtime binding that doesn't exist and will produce a TypeScript 
compile error. Use a type-only export (`export type { ... }`) to re-export the 
type. [type error]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ superset-frontend TypeScript build failure.
   - ❌ CI frontend build job fails blocking deployments.
   - ⚠️ Local developer typecheck/watch sessions error.
   ```
   </details>
   
   ```suggestion
   export type { SegmentedProps };
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. From the repository root run the frontend typecheck/build (e.g., `yarn 
build` or the
   monorepo TypeScript build). The TypeScript compiler will read the file at
   
`superset-frontend/packages/superset-ui-core/src/components/Segmented/types.ts:19-21`.
   
   2. TypeScript resolves the `import type { SegmentedProps }` at line 19 and 
then encounters
   `export { SegmentedProps };` at line 21 which attempts to export a runtime 
binding that
   does not exist.
   
   3. The compiler emits an error during the build/typecheck step referencing
   `.../Segmented/types.ts:21` and the build fails (CI/frontend build job fails 
at the
   TypeScript phase).
   
   4. Confirm reproduction by opening
   
`superset-frontend/packages/superset-ui-core/src/components/Segmented/types.ts` 
and
   running `tsc --noEmit` locally; the error points to line 21 showing the 
invalid re-export
   of a type-only import.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** 
superset-frontend/packages/superset-ui-core/src/components/Segmented/types.ts
   **Line:** 21:21
   **Comment:**
        *Type Error: Type-only import is being re-exported as a value: `import 
type { SegmentedProps }` followed by `export { SegmentedProps }` attempts to 
export a runtime binding that doesn't exist and will produce a TypeScript 
compile error. Use a type-only export (`export type { ... }`) to re-export the 
type.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>



##########
superset-frontend/src/SqlLab/components/TableExploreTree/index.tsx:
##########
@@ -0,0 +1,685 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {
+  useMemo,
+  useCallback,
+  useState,
+  useRef,
+  type ChangeEvent,
+} from 'react';
+import { useSelector, useDispatch, shallowEqual } from 'react-redux';
+import { css, styled, t } from '@apache-superset/core';
+import AutoSizer from 'react-virtualized-auto-sizer';
+// Due to performance issues with the virtual list in the existing Ant Design 
(antd)-based tree view,
+// it has been replaced with react-arborist solution.
+import { Tree, TreeApi, NodeRendererProps, NodeApi } from 'react-arborist';
+import {
+  Icons,
+  Skeleton,
+  Input,
+  Tooltip,
+  Empty,
+  Typography,
+  Button,
+} from '@superset-ui/core/components';
+import RefreshLabel from '@superset-ui/core/components/RefreshLabel';
+import type { SqlLabRootState } from 'src/SqlLab/types';
+import ColumnElement, {
+  type ColumnKeyTypeType,
+} from 'src/SqlLab/components/ColumnElement';
+import {
+  Table,
+  TableMetaData,
+  useSchemas,
+  useLazyTablesQuery,
+  useLazyTableMetadataQuery,
+  useLazyTableExtendedMetadataQuery,
+} from 'src/hooks/apiResources';
+import useQueryEditor from 'src/SqlLab/hooks/useQueryEditor';
+import { addTable } from 'src/SqlLab/actions/sqlLab';
+import IconButton from 'src/dashboard/components/IconButton';
+import ButtonCell from 
'@superset-ui/core/components/Table/cell-renderers/ButtonCell';
+
+type Props = {
+  queryEditorId: string;
+};
+
+interface TreeNodeData {
+  id: string;
+  name: string;
+  type: 'schema' | 'table' | 'column' | 'empty';
+  tableType?: string;
+  columnData?: {
+    name: string;
+    keys?: { type: ColumnKeyTypeType }[];
+    type: string;
+  };
+  children?: TreeNodeData[];
+  disableCheckbox?: boolean;
+}
+
+const EMPTY_NODE_ID_PREFIX = 'empty:';
+
+const StyledTreeContainer = styled.div`
+  flex: 1 1 auto;
+  .tree-node {
+    display: flex;
+    align-items: center;
+    padding: 0 ${({ theme }) => theme.sizeUnit}px;
+    position: relative;
+    cursor: pointer;
+
+    &:hover {
+      background-color: ${({ theme }) => theme.colorBgTextHover};
+
+      .side-action-container {
+        opacity: 1;
+      }
+    }
+
+    &[data-selected='true'] {
+      background-color: ${({ theme }) => theme.colorBgTextActive};
+
+      .side-action-container {
+        opacity: 1;
+      }
+    }
+  }
+
+  .tree-node-icon {
+    margin-right: ${({ theme }) => theme.sizeUnit}px;
+    display: flex;
+    align-items: center;
+    gap: ${({ theme }) => theme.sizeUnit}px;
+  }
+
+  .tree-node-title {
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    flex: 1;
+  }
+
+  .highlighted {
+    background-color: ${({ theme }) => theme.colorWarningBg};
+    font-weight: bold;
+  }
+
+  .side-action-container {
+    opacity: 0;
+    position: absolute;
+    right: ${({ theme }) => theme.sizeUnit * 1.5}px;
+    top: 50%;
+    transform: translateY(-50%);
+    z-index: ${({ theme }) => theme.zIndexPopupBase};
+  }
+`;
+
+const ROW_HEIGHT = 28;
+
+const getOpacity = (disableCheckbox: boolean | undefined) => ({
+  opacity: disableCheckbox ? 0.6 : 1,
+});
+
+const highlightText = (text: string, keyword: string): React.ReactNode => {
+  if (!keyword) {
+    return text;
+  }
+
+  const lowerText = text.toLowerCase();
+  const lowerKeyword = keyword.toLowerCase();
+  const index = lowerText.indexOf(lowerKeyword);
+
+  if (index === -1) {
+    return text;
+  }
+
+  const beforeStr = text.substring(0, index);
+  const matchStr = text.substring(index, index + keyword.length);
+  const afterStr = text.slice(index + keyword.length);
+
+  return (
+    <>
+      {beforeStr}
+      <span className="highlighted">{matchStr}</span>
+      {afterStr}
+    </>
+  );
+};
+
+const TableExploreTree: React.FC<Props> = ({ queryEditorId }) => {
+  const dispatch = useDispatch();
+  const treeRef = useRef<TreeApi<TreeNodeData>>(null);
+  const tables = useSelector(
+    ({ sqlLab }: SqlLabRootState) => sqlLab.tables,
+    shallowEqual,
+  );
+  const queryEditor = useQueryEditor(queryEditorId, [
+    'dbId',
+    'schema',
+    'catalog',
+  ]);
+  const { dbId, catalog } = queryEditor;
+  const pinnedTables = useMemo(
+    () =>
+      Object.fromEntries(
+        tables.map(({ queryEditorId, dbId, schema, name, persistData }) => [
+          queryEditor.id === queryEditorId ? `${dbId}:${schema}:${name}` : '',
+          persistData,
+        ]),
+      ),
+    [tables, queryEditor.id],
+  );
+  const {
+    currentData: schemaData,
+    isFetching,
+    refetch,
+  } = useSchemas({ dbId, catalog: catalog || undefined });
+  const [tableData, setTableData] =
+    useState<Record<string, { options: Table[] }>>();

Review Comment:
   **Suggestion:** Runtime error: `tableData` is initialized as undefined, but 
later updates spread the previous state (e.g. `{ ...origin, [schemaKey]: data 
}`), which will throw when `origin` is undefined; initialize `tableData` to an 
empty object to avoid spreading `undefined`. [possible bug]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ Expanding schema crashes tree UI.
   - ⚠️ Table children fail to populate for schemas.
   ```
   </details>
   
   ```suggestion
       useState<Record<string, { options: Table[] }>>({});
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Render the TableExploreTree component (file:
   superset-frontend/src/SqlLab/components/TableExploreTree/index.tsx). 
tableData is
   initialized at lines 194-195 as undefined.
   
   2. Expand a schema node in the UI (user clicks the schema row). The Tree 
onToggle handler
   at lines ~655-673 calls handleToggle for that node id.
   
   3. handleToggle (file lines 328-431) detects identifier === 'schema', calls
   fetchLazyTables(...). In the .then() handler (lines ~355-363) it calls 
setTableData(origin
   => ({ ...origin, [schemaKey]: data })).
   
   4. Because the initial state origin is undefined, spreading origin causes a 
runtime
   TypeError (spreading non-object) at the .then() handler, observed as an 
exception when
   expanding any schema for the first time.
   
   5. Initializing tableData to an empty object (improved code) prevents 
spreading undefined
   and resolves the crash when loading tables for a schema.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset-frontend/src/SqlLab/components/TableExploreTree/index.tsx
   **Line:** 195:195
   **Comment:**
        *Possible Bug: Runtime error: `tableData` is initialized as undefined, 
but later updates spread the previous state (e.g. `{ ...origin, [schemaKey]: 
data }`), which will throw when `origin` is undefined; initialize `tableData` 
to an empty object to avoid spreading `undefined`.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to