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(ui): debug preview #1007

Merged
merged 21 commits into from
Mar 14, 2025
Merged

feat(ui): debug preview #1007

merged 21 commits into from
Mar 14, 2025

Conversation

KaWaite
Copy link
Member

@KaWaite KaWaite commented Mar 10, 2025

Overview

What I've done

What I haven't done

How I tested

Screenshot

Which point I want you to review particularly

Memo

Summary by CodeRabbit

  • New Features

    • Introduced enhanced GeoJSON visualization for 3D maps.
    • Added an interactive Debug Preview panel featuring both Data Viewer and 3D Viewer modes.
    • Rolled out a new geo-data display component for improved spatial rendering.
  • Style

    • Refined padding and background styling in selection components.
    • Increased the text area’s maximum height for better content display.
    • Enhanced layout and controls within debug logs and overlay elements.
  • Refactor

    • Streamlined job status and real-time log handling.
    • Updated localized messages to support the new data preview features.

Copy link
Contributor

coderabbitai bot commented Mar 10, 2025

Walkthrough

The diff includes extensive UI and state management updates across many modules. Several components have been restyled with updated class names and adjusted layout properties. Old components (e.g., CesiumContents, DataTable, Map, Contents) have been removed in favor of new components like GeoJsonData and DebugPreview with associated subcomponents. Hooks for data fetching, subscriptions, and job status have been refactored and expanded, and the GraphQL subscription logic has been overhauled. Additionally, localization files now include new keys for data preview while removing outdated texts, and new GIS types and utilities have been added.

Changes

File(s) Change Summary
ui/src/components/Select/index.tsx
ui/src/components/TextArea/index.tsx
Updated styling: replaced paddings in Select and increased TextArea max-height.
ui/src/components/visualizations/Cesium/Contents.tsx
ui/src/components/visualizations/Cesium/GeoJson.tsx
ui/src/components/visualizations/Cesium/index.tsx
Removed CesiumContents, added new GeoJsonData component, and updated CesiumViewer props and default settings.
ui/src/features/Editor/components/BottomBar/components/Contents/index.tsx
.../DataTable/index.tsx
.../Map/index.tsx
ui/src/features/Editor/components/BottomBar/hooks.tsx
ui/src/features/Editor/components/BottomBar/index.tsx
Removed Contents, DataTable, and Map components; simplified hook logic and removed isOpen/onOpen props from BottomBar.
ui/src/features/Editor/components/LeftPanel/index.tsx Updated the Props type: restricted onOpen to "left" or "right" and added an optional selected node property.
ui/src/features/Editor/components/OverlayUI/components/CanvasActionbar/index.tsx
ui/src/features/Editor/components/OverlayUI/components/DebugLogs/hooks.ts
.../DebugLogs/index.tsx
.../DebugPreview/components/DataTable/index.tsx
.../DebugPreview/hooks.ts
.../DebugPreview/index.tsx
.../LayoutOptionsDialog/index.tsx
.../NodePickerDialog/index.tsx
ui/src/features/Editor/components/OverlayUI/components/index.ts
ui/src/features/Editor/components/OverlayUI/index.tsx
Updated CanvasActionBar class; adjusted DebugLogs heights and toggle logic; added DebugPreview (with DataTable and GeoMap subcomponents) and memoized LayoutOptionsDialog/NodePickerDialog; exported DebugPreview via the components index and integrated it into OverlayUI.
ui/src/features/Editor/index.tsx
ui/src/features/Editor/useUIState.ts
Removed bottom bar props from Editor and limited panel choices in state to "left" or "right".
ui/src/features/LogsConsole/index.tsx
ui/src/features/WorkspaceJobs/components/JobDetails/hooks.ts
ui/src/features/WorkspaceJobs/components/JobDetails/index.tsx
Switched from the useLogs hook to useSubscription; updated JobDetails to accept an accessToken and refactored job status retrieval.
ui/src/hooks/index.ts
ui/src/hooks/useDataColumnizer.ts
ui/src/hooks/useFetchAndReadData.ts
ui/src/hooks/useJobSubscriptionsSetup.ts
Added new hooks: useJobSubscriptionsSetup, useDataColumnizer, useFetchAndReadData; exported the job subscriptions hook.
ui/src/lib/gql/job/index.ts
ui/src/lib/gql/job/useSubscriptions.ts
ui/src/lib/gql/provider/GraphQLSubscriptionProvider.tsx
ui/src/lib/gql/provider/index.tsx
ui/src/lib/gql/realTimeLogs/useSubscriptions.ts
ui/src/lib/gql/subscriptions/useSubscription.ts
ui/src/lib/gql/subscriptions/useSubscriptionSetup.ts
Removed legacy GraphQL subscription hooks and providers; introduced new useSubscription and useSubscriptionSetup methods with associated enums/types.
ui/src/lib/i18n/locales/en.json
.../es.json
.../fr.json
.../ja.json
.../zh.json
Removed the deprecated "3D visualization is not supported" (and in some locales "Loading...") text; added new keys for "Select Data to Preview", " (Output data)", "Data Viewer", and "3D Viewer" (with translations where applicable).
ui/src/lib/yjs/useYjsSetup.ts
ui/src/mock_data/pointData/index.ts
Reorganized cleanup in the Yjs hook; removed the mock fire data export (points).
ui/src/routes/workspaces.$workspaceId.jobs_.$jobId.tsx
ui/src/routes/workspaces.$workspaceId_.projects_.$projectId.lazy.tsx
Introduced accessToken state handling in routes; integrated hooks for job subscriptions, IndexedDB, and current project retrieval.
ui/src/types/gisTypes/common.ts
ui/src/types/gisTypes/geoJSON/Polygon.ts
ui/src/types/gisTypes/geoJSON/index.ts
Added a new type Coordinate and created GeoJSON Polygon types; re-exported Polygon definitions via the geoJSON index.
ui/src/utils/fetchAndReadGeoData.ts Added a new utility file that defines SupportedDataTypes (limited to "geojson") and implements the fetchAndReadData function.
ui/src/features/Editor/components/OverlayUI/components/DebugPreview/components/GeoMap/index.tsx
ui/src/features/Editor/components/OverlayUI/components/DebugPreview/components/index.ts
Added new GeoMap component replacing the former Map export for DebugPreview; passes fileContent and fileType to CesiumViewer.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant DP as DebugPreview Component
    participant F as useFetchAndReadData Hook
    participant DT as DebugPreview DataTable
    participant CV as CesiumViewer Component

    U->>DP: Select data from dropdown
    DP->>F: Fetch file content & type
    F-->>DP: Return data payload
    alt Data is GeoJSON
      DP->>DT: Render Data Viewer with table
    else
      DP->>CV: Render 3D Viewer with Cesium
    end
Loading
sequenceDiagram
    participant C as Component
    participant S as useSubscriptionSetup Hook
    participant WS as WebSocket Client
    participant QC as Query Client

    C->>S: Initialize subscription (jobId, accessToken)
    S->>WS: Establish WebSocket connection
    WS-->>S: Receive job status/log updates
    S->>QC: Update React Query cache with new data
    QC-->>C: Provide updated subscription data
Loading

Poem

Oh, what a day for a rabbit so bright,
New code and hooks, a delightful sight!
Old parts retire, while fresh ones appear,
With clearer state and data so dear.
Hop along the streams of GraphQL flow,
Debug and preview—let innovation glow!
🐰💻 Happy coding, my friend—let’s go!

Tip

⚡🧪 Multi-step agentic review comment chat (experimental)
  • We're introducing multi-step agentic chat in review comments. This experimental feature enhances review discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments.
    - To enable this feature, set early_access to true under in the settings.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
  • @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.

Copy link

netlify bot commented Mar 10, 2025

Deploy Preview for reearth-flow ready!

Name Link
🔨 Latest commit 21f0aa6
🔍 Latest deploy log https://app.netlify.com/sites/reearth-flow/deploys/67d38995b032930008c5f0b5
😎 Deploy Preview https://deploy-preview-1007--reearth-flow.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@KaWaite KaWaite marked this pull request as ready for review March 14, 2025 00:55
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 comments (1)
ui/src/features/Editor/components/OverlayUI/components/DebugPreview/components/Map/index.tsx (1)

1-19: ⚠️ Potential issue

Rename component to avoid shadowing global Map object

The component name "Map" shadows the global JavaScript Map object, which could lead to confusion or bugs in the codebase.

Apply this change to rename the component to something more specific:

-const Map: React.FC<Props> = ({ className, fileContent, fileType }) => {
+const GeoMap: React.FC<Props> = ({ className, fileContent, fileType }) => {
  return (
    <div className={`relative size-full ${className}`}>
      <CesiumViewer fileContent={fileContent} fileType={fileType} />
    </div>
  );
};

-export { Map };
+export { GeoMap };

Also update import statements wherever this component is used.

🧰 Tools
🪛 Biome (1.9.4)

[error] 10-10: Do not shadow the global "Map" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🧹 Nitpick comments (25)
ui/src/lib/i18n/locales/zh.json (1)

92-95: Missing Chinese translations for new UI elements.

The translation keys have been added, but the actual Chinese translations are empty. Consider providing translations for these strings to maintain a consistent user experience across languages.

-  "Select Data to Preview": "",
-  " (Output data)": "",
-  "Data Viewer": "",
-  "3D Viewer": "",
+  "Select Data to Preview": "选择要预览的数据",
+  " (Output data)": " (输出数据)",
+  "Data Viewer": "数据查看器",
+  "3D Viewer": "3D查看器",
ui/src/features/Editor/components/OverlayUI/components/DebugPreview/components/Map/index.tsx (1)

12-14: Consider handling empty state or loading state

The component doesn't handle cases where fileContent or fileType might be null, which could result in rendering issues in the CesiumViewer.

Consider adding conditional rendering or a fallback message:

 <div className={`relative size-full ${className}`}>
-  <CesiumViewer fileContent={fileContent} fileType={fileType} />
+  {fileContent && fileType ? (
+    <CesiumViewer fileContent={fileContent} fileType={fileType} />
+  ) : (
+    <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
+      No map data available
+    </div>
+  )}
 </div>
ui/src/features/Editor/components/OverlayUI/components/DebugLogs/index.tsx (1)

28-36: Consider adding tooltips for better UX

While the current implementation is clear with the icon indicators, adding tooltips would improve accessibility and user experience.

{!minimized && (
-  <div className="rounded p-1 hover:bg-primary">
+  <div 
+    className="rounded p-1 hover:bg-primary" 
+    title={expanded ? "Collapse" : "Expand"}>
    {expanded ? (
      <CaretDown weight="light" />
    ) : (
      <CaretUp weight="light" />
    )}
  </div>
)}

Also consider adding a tooltip to the minimize button:

<div
-  className="rounded p-1 hover:bg-primary"
+  className="rounded p-1 hover:bg-primary"
+  title={minimized ? "Restore" : "Minimize"}
  onClick={handleMinimize}>
  {minimized ? <CaretUp weight="light" /> : <Minus weight="light" />}
</div>
ui/src/components/Select/index.tsx (1)

27-27: Horizontal padding adjustment

The horizontal padding of the SelectTrigger has been changed from uniform px-3 to asymmetric pl-2 pr-1. This creates a slightly tighter layout with less padding on the right side, which may be intended to better accommodate the dropdown icon.

ui/src/lib/gql/subscriptions/useSubscription.ts (1)

13-20: Unused disabled parameter and commented code

The _disabled parameter is declared but not used in the function, with a commented line that suggests it was intended to control whether the query is enabled.

Either implement the disabled functionality or remove the unused parameter:

export function useSubscription(
  subscriptionKey: PossibleSubscriptionKeys,
  secondaryCacheKey?: string,
-  _disabled?: boolean,
+  disabled?: boolean,
) {
  return useQuery({
    queryKey: [SubscriptionKeys[subscriptionKey], secondaryCacheKey],
    queryFn: () => undefined,
    gcTime: Infinity,
    staleTime: Infinity,
-    enabled: true,
+    enabled: disabled === undefined ? true : !disabled,
    // enabled: disabled ?! disabled : false,
  });
}
ui/src/hooks/useFetchAndReadData.ts (1)

20-21: Consider additional validation for empty dataUrl

The current check might trigger unnecessary fetches when fileContent is null. Consider adding a check for empty dataUrl.

  useEffect(() => {
-   if (!fileContent || dataUrl !== prevDataUrl.current) {
+   if (dataUrl && (!fileContent || dataUrl !== prevDataUrl.current)) {
      setIsLoading(true);
      setError(null);
ui/src/components/visualizations/Cesium/GeoJson.tsx (2)

8-15: Consider fixing the ESLint disable line.

While the component logic is correct, the ESLint disable comment for the react-hooks/exhaustive-deps rule could be improved by adding dataSourceKey to the dependency array instead of disabling the rule.

-  }, [geoJsonData]); // eslint-disable-line react-hooks/exhaustive-deps
+  }, [geoJsonData, dataSourceKey]);

22-33: Consider implementing the commented styling code.

The commented styling code suggests an intention to add custom styling for GeoJSON entities. Consider implementing this to enhance the visual representation of the data.

ui/src/components/visualizations/Cesium/index.tsx (1)

33-36: Consider revisiting the isLoaded state implementation.

The isLoaded state is only set once and never changed back. Consider whether this state is necessary or if it could be replaced with a simpler approach.

-  const [isLoaded, setIsLoaded] = useState(false);
-
-  useEffect(() => {
-    if (isLoaded) return;
-    setIsLoaded(true);
-  }, [isLoaded]);
+  // Using useState with a default value of true since we only need to render once
+  const [isLoaded] = useState(true);
ui/src/features/Editor/components/OverlayUI/components/DebugPreview/hooks.ts (2)

25-25: Consider adding error handling for job data retrieval.

The hook retrieves outputURLs directly from the job object but doesn't handle the case where useGetJob might be loading or if it encounters an error.

-  const outputURLs = useGetJob(debugJobId ?? "").job?.outputURLs;
+  const { job, loading, error } = useGetJob(debugJobId ?? "");
+  const outputURLs = job?.outputURLs;

39-41: Prevent unnecessary API calls with empty URL.

The useFetchAndReadData hook is called with a potentially empty string URL when selectedDataURL is null, which might cause unnecessary API calls or errors.

-  const { fileContent, fileType } = useFetchAndReadData({
-    dataUrl: selectedDataURL ?? "",
-  });
+  const { fileContent, fileType } = useFetchAndReadData({
+    dataUrl: selectedDataURL || undefined,
+  });
ui/src/utils/fetchAndReadGeoData.ts (4)

3-7: Consider using more specific types

The fileContent return type is set to any, which is not type-safe. Consider defining a more specific type for GeoJSON data.

- export async function fetchAndReadData(fileUrl: string): Promise<{
-   fileContent: any;
-   type: SupportedDataTypes | null;
-   error: string | null;
- }> {
+ export async function fetchAndReadData(fileUrl: string): Promise<{
+   fileContent: GeoJSON.GeoJSON | null;
+   type: SupportedDataTypes | null;
+   error: string | null;
+ }> {

You'd need to import the GeoJSON type either from a library like @types/geojson or define it yourself.


21-26: Consider checking MIME type instead of file extension

Currently, the function relies on the file extension to determine the file type. This approach might not work for URLs that don't have a clear file extension or when the extension doesn't match the content.

- const fileExtension = fileUrl.split(".").pop()?.toLowerCase();
- if (fileExtension === "geojson") {
+ const contentType = response.headers.get("content-type");
+ if (fileExtension === "geojson" || contentType?.includes("application/geo+json")) {

27-28: Remove console.log statement

There's a console.log statement that should be removed or replaced with proper logging.

- console.log("didn't get geojson");

1-41: Validate GeoJSON data structure

The function parses the JSON but doesn't validate that it's actually valid GeoJSON. Consider adding validation to prevent issues downstream.

You could add a function to validate GeoJSON structure before returning it:

function isValidGeoJSON(data: any): boolean {
  // Check if data has the required properties of a GeoJSON object
  if (!data || typeof data !== "object") return false;
  
  // GeoJSON must have a "type" property
  if (!data.type) return false;
  
  // For Feature type, it must have geometry and properties
  if (data.type === "Feature") {
    return !!data.geometry && data.properties !== undefined;
  }
  
  // For FeatureCollection, it must have features array
  if (data.type === "FeatureCollection") {
    return Array.isArray(data.features);
  }
  
  // For geometry types, they must have coordinates
  if (["Point", "LineString", "Polygon", "MultiPoint", "MultiLineString", "MultiPolygon"].includes(data.type)) {
    return Array.isArray(data.coordinates);
  }
  
  return false;
}

// Then in your fetchAndReadData function:
if (isValidGeoJSON(parsedData)) {
  return { fileContent: parsedData, type: "geojson", error: null };
} else {
  return {
    fileContent: null,
    type: null,
    error: "Invalid GeoJSON format",
  };
}
ui/src/features/Editor/components/OverlayUI/components/DebugPreview/index.tsx (2)

43-44: Consider making dimensions more responsive.

The component uses fixed pixel values for width/height which might not work well on all screen sizes.

-      className={`pointer-events-auto w-[45vw] min-w-[700px] rounded border bg-secondary transition-all ${minimized ? "h-[36px]" : expanded ? "h-[85vh] w-[90vw]" : "h-[500px]"}`}
+      className={`pointer-events-auto w-[45vw] min-w-[300px] max-w-[90vw] rounded border bg-secondary transition-all ${minimized ? "h-[36px]" : expanded ? "h-[85vh] w-[90vw]" : "h-[500px]"}`}

54-59: Improve SelectItem key and displayed text.

Using the last segment of the URL as both key and display text might lead to non-unique keys if multiple files have the same name. Also, the translation string has a hard-coded space at the beginning.

{outputURLs.map((url) => (
  <SelectItem key={url} value={url}>
    {url.split("/").pop()}
-   {t(" (Output data)")}
+   {t("(Output data)")}
  </SelectItem>
))}
ui/src/lib/gql/subscriptions/useSubscriptionSetup.ts (3)

70-76: Use more specific TypeScript types instead of 'any'.

Using any types reduces type safety and IDE autocompletion benefits. Consider using more specific types.

-export function useSubscriptionSetup<Data = any, CachedData = any>(
+export function useSubscriptionSetup<Data = Record<string, unknown>, CachedData = Record<string, unknown>>(
  subscriptionKey: PossibleSubscriptionKeys,
  accessToken: string | undefined,
  variables: Record<string, unknown>,
  secondaryCacheKey?: string,
-  dataFormatter?: (data: Data, cachedData?: CachedData) => unknown | undefined,
+  dataFormatter?: (data: Data, cachedData?: CachedData) => CachedData | undefined,
  disabled?: boolean,
)

48-58: Implement a more refined retry strategy for WebSocket connections.

The current implementation always retries 5 times regardless of the error type, which might lead to unnecessary retries for permanent errors.

const newClient = createClient({
  url,
  retryAttempts: 5,
- shouldRetry: () => true,
+ shouldRetry: (error) => {
+   // Don't retry for authentication errors or other permanent failures
+   if (error instanceof Error && error.message.includes('Unauthorized')) {
+     return false;
+   }
+   return true;
+ },
  connectionParams: () => ({
    headers: {
      authorization: `Bearer ${accessToken}`,
    },
  }),
  lazy: true,
});

117-119: Improve error handling for subscription errors.

The current implementation only logs errors to the console without any user notification or error recovery mechanism.

Consider implementing a more robust error handling approach:

error: (err) => {
  console.error(`Subscription error for ${subscriptionKey}: `, err);
+ // Optionally, update a React Query error state that can be used for UI error displays
+ queryClient.setQueryData(
+   [SubscriptionKeys[subscriptionKey], secondaryCacheKey, 'error'],
+   err
+ );
},
ui/src/hooks/useDataColumnizer.ts (5)

7-13: Use more specific TypeScript types instead of 'any'.

Using any types reduces type safety and IDE autocompletion benefits.

export default ({
  parsedData,
  type,
}: {
-  parsedData?: any;
+  parsedData?: Record<string, unknown>;
  type?: SupportedDataTypes | null;
})

91-104: Remove commented out code.

The file contains commented out code for CSV handling that should either be implemented or removed.

Either implement the CSV handling functionality or remove the commented code to keep the codebase clean.


25-31: Use TypeScript interfaces for GeoJSON feature types.

The code uses any for feature types, which loses type safety. Consider importing or defining proper GeoJSON interfaces.

+ // Add a proper interface for GeoJSON features
+ interface GeoJSONFeature {
+   id?: string | number;
+   type: string;
+   geometry: {
+     type: string;
+     coordinates: any;
+     [key: string]: any;
+   };
+   properties?: Record<string, any>;
+ }

// Then use this interface instead of 'any'
- features.forEach((feature: any) => {
+ features.forEach((feature: GeoJSONFeature) => {
  if (feature.geometry) {
    Object.keys(feature.geometry).forEach((key) =>
      allGeometry.add(key),
    );
  }
});

147-154: Improve error handling in simplifyPolygonCoordinates.

The function throws a generic error on invalid input, which might not be helpful for debugging.

function simplifyPolygonCoordinates(polygon: Polygon) {
  if (
    !polygon ||
    polygon.type !== "Polygon" ||
    !Array.isArray(polygon.coordinates)
  ) {
-    throw new Error("Invalid GeoJSON Polygon");
+    throw new Error(
+      `Invalid GeoJSON Polygon: expected array coordinates but got ${polygon?.coordinates ? typeof polygon.coordinates : 'undefined'}`
+    );
  }

60-85: Consider memoizing the tableData transformation.

The features-to-tableData transformation could be expensive for large datasets and is recalculated on each render.

Consider using useMemo to memoize the transformation:

const tableData = useMemo(() => 
  features.map((feature: any, index: number) => ({
    id: JSON.stringify(feature.id || index),
    ...Object.fromEntries(
      Array.from(allGeometry).map((geometry) => {
        if (
          geometry === "coordinates" &&
          feature.geometry.type === "Polygon"
        ) {
          return [
            `geometry${geometry}`,
            simplifyPolygonCoordinates(feature.geometry),
          ];
        }
        return [
          `geometry${geometry}`,
          JSON.stringify(feature.geometry?.[geometry] || null),
        ];
      }),
    ),
    ...Object.fromEntries(
      Array.from(allProps).map((prop) => [
        `properties${prop}`,
        JSON.stringify(feature.properties?.[prop] || null),
      ]),
    ),
  })),
  [features, allGeometry, allProps]
);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c3b3a75 and 02c2669.

📒 Files selected for processing (51)
  • ui/src/components/Select/index.tsx (2 hunks)
  • ui/src/components/TextArea/index.tsx (1 hunks)
  • ui/src/components/visualizations/Cesium/Contents.tsx (0 hunks)
  • ui/src/components/visualizations/Cesium/GeoJson.tsx (1 hunks)
  • ui/src/components/visualizations/Cesium/index.tsx (2 hunks)
  • ui/src/features/Editor/components/BottomBar/components/Contents/index.tsx (0 hunks)
  • ui/src/features/Editor/components/BottomBar/components/DataTable/index.tsx (0 hunks)
  • ui/src/features/Editor/components/BottomBar/components/Map/index.tsx (0 hunks)
  • ui/src/features/Editor/components/BottomBar/hooks.tsx (2 hunks)
  • ui/src/features/Editor/components/BottomBar/index.tsx (2 hunks)
  • ui/src/features/Editor/components/LeftPanel/index.tsx (1 hunks)
  • ui/src/features/Editor/components/OverlayUI/components/CanvasActionbar/index.tsx (1 hunks)
  • ui/src/features/Editor/components/OverlayUI/components/DebugLogs/hooks.ts (1 hunks)
  • ui/src/features/Editor/components/OverlayUI/components/DebugLogs/index.tsx (2 hunks)
  • ui/src/features/Editor/components/OverlayUI/components/DebugPreview/components/DataTable/index.tsx (1 hunks)
  • ui/src/features/Editor/components/OverlayUI/components/DebugPreview/components/Map/index.tsx (1 hunks)
  • ui/src/features/Editor/components/OverlayUI/components/DebugPreview/hooks.ts (1 hunks)
  • ui/src/features/Editor/components/OverlayUI/components/DebugPreview/index.tsx (1 hunks)
  • ui/src/features/Editor/components/OverlayUI/components/LayoutOptionsDialog/index.tsx (2 hunks)
  • ui/src/features/Editor/components/OverlayUI/components/NodePickerDialog/index.tsx (2 hunks)
  • ui/src/features/Editor/components/OverlayUI/components/index.ts (1 hunks)
  • ui/src/features/Editor/components/OverlayUI/index.tsx (2 hunks)
  • ui/src/features/Editor/index.tsx (0 hunks)
  • ui/src/features/Editor/useUIState.ts (1 hunks)
  • ui/src/features/LogsConsole/index.tsx (3 hunks)
  • ui/src/features/WorkspaceJobs/components/JobDetails/hooks.ts (4 hunks)
  • ui/src/features/WorkspaceJobs/components/JobDetails/index.tsx (2 hunks)
  • ui/src/hooks/index.ts (1 hunks)
  • ui/src/hooks/useDataColumnizer.ts (1 hunks)
  • ui/src/hooks/useFetchAndReadData.ts (1 hunks)
  • ui/src/hooks/useJobSubscriptionsSetup.ts (1 hunks)
  • ui/src/lib/gql/job/index.ts (0 hunks)
  • ui/src/lib/gql/job/useSubscriptions.ts (0 hunks)
  • ui/src/lib/gql/provider/GraphQLSubscriptionProvider.tsx (0 hunks)
  • ui/src/lib/gql/provider/index.tsx (1 hunks)
  • ui/src/lib/gql/realTimeLogs/useSubscriptions.ts (0 hunks)
  • ui/src/lib/gql/subscriptions/useSubscription.ts (1 hunks)
  • ui/src/lib/gql/subscriptions/useSubscriptionSetup.ts (1 hunks)
  • ui/src/lib/i18n/locales/en.json (1 hunks)
  • ui/src/lib/i18n/locales/es.json (1 hunks)
  • ui/src/lib/i18n/locales/fr.json (1 hunks)
  • ui/src/lib/i18n/locales/ja.json (1 hunks)
  • ui/src/lib/i18n/locales/zh.json (1 hunks)
  • ui/src/lib/yjs/useYjsSetup.ts (1 hunks)
  • ui/src/mock_data/pointData/index.ts (0 hunks)
  • ui/src/routes/workspaces.$workspaceId.jobs_.$jobId.tsx (2 hunks)
  • ui/src/routes/workspaces.$workspaceId_.projects_.$projectId.lazy.tsx (3 hunks)
  • ui/src/types/gisTypes/common.ts (1 hunks)
  • ui/src/types/gisTypes/geoJSON/Polygon.ts (1 hunks)
  • ui/src/types/gisTypes/geoJSON/index.ts (1 hunks)
  • ui/src/utils/fetchAndReadGeoData.ts (1 hunks)
💤 Files with no reviewable changes (10)
  • ui/src/components/visualizations/Cesium/Contents.tsx
  • ui/src/lib/gql/job/index.ts
  • ui/src/features/Editor/components/BottomBar/components/Map/index.tsx
  • ui/src/mock_data/pointData/index.ts
  • ui/src/features/Editor/index.tsx
  • ui/src/features/Editor/components/BottomBar/components/Contents/index.tsx
  • ui/src/lib/gql/realTimeLogs/useSubscriptions.ts
  • ui/src/features/Editor/components/BottomBar/components/DataTable/index.tsx
  • ui/src/lib/gql/provider/GraphQLSubscriptionProvider.tsx
  • ui/src/lib/gql/job/useSubscriptions.ts
🧰 Additional context used
🪛 Biome (1.9.4)
ui/src/features/Editor/components/OverlayUI/components/DebugPreview/components/Map/index.tsx

[error] 10-10: Do not shadow the global "Map" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

ui/src/features/Editor/components/OverlayUI/components/DebugPreview/index.tsx

[error] 24-24: Do not shadow the global "Map" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Collect information
🔇 Additional comments (75)
ui/src/lib/gql/provider/index.tsx (1)

16-16:

❓ Verification inconclusive

Architecture change: GraphQLSubscriptionProvider removed

The removal of the GraphQLSubscriptionProvider simplifies the component hierarchy. This appears to be part of a larger refactoring of subscription handling across the application.

Please confirm that:

  1. Components previously relying on the GraphQLSubscriptionProvider have been updated to use the new approach
  2. Real-time functionality previously handled by this provider is either maintained through alternative means or intentionally removed

🏁 Script executed:

#!/bin/bash
# Check for any remaining references to GraphQLSubscriptionProvider that might need updating
echo "Checking for remaining references to GraphQLSubscriptionProvider..."
rg "GraphQLSubscriptionProvider" --type tsx --type ts

Length of output: 226


Below is a revised approach designed to verify that GraphQLSubscriptionProvider is fully removed from the codebase. Since the previous command noted an unrecognized file type for .tsx, please run the following shell script to search both .tsx and .ts files:

Once executed, please confirm that no references to GraphQLSubscriptionProvider remain. Additionally, verify that any components previously dependent on this provider have been updated to support the new approach (whether real-time functionality is now handled differently or has been intentionally removed).


Architecture Update: Removal of GraphQLSubscriptionProvider

The updated code now directly renders {children}, reflecting our broader refactor of GraphQL subscription handling. Please verify the following:

  • Components formerly relying on GraphQLSubscriptionProvider are updated appropriately.
  • Real-time functionality provided by the removed provider is either maintained via alternative methods or has been intentionally deprecated.

🏁 Script executed:

#!/bin/bash
echo "Searching for GraphQLSubscriptionProvider in .tsx files using fd and grep..."
fd -e tsx -x grep -H "GraphQLSubscriptionProvider" {}
echo "Searching for GraphQLSubscriptionProvider in .ts files using fd and grep..."
fd -e ts -x grep -H "GraphQLSubscriptionProvider" {}

Length of output: 434


Architecture update: Removal of GraphQLSubscriptionProvider confirmed

The shell script verification indicates that there are no remaining references to GraphQLSubscriptionProvider in either .tsx or .ts files, which aligns with the intentional architectural change. The file now directly renders {children}, thereby simplifying the component hierarchy as part of the refactor.

  • Please manually verify that any components previously relying on GraphQLSubscriptionProvider have been updated to work with the new subscription handling approach.
  • Confirm that real-time functionality is either maintained using the new setup or has been intentionally removed as part of this refactor.
ui/src/lib/yjs/useYjsSetup.ts (1)

78-79: Code cleanup improvement.

The reordering of these lines in the cleanup function improves code readability by removing inline comments while preserving the same logical flow.

ui/src/lib/i18n/locales/es.json (1)

92-95: New translations added for debug preview feature.

These new translation entries support the debug preview functionality, providing Spanish localization for the data selection and viewer components.

ui/src/types/gisTypes/common.ts (1)

1-1: Well-defined coordinate type for GIS functionality.

Good addition of the Coordinate type that provides a clear definition for geographical coordinate pairs. This will enhance type safety when working with map or GeoJSON data.

ui/src/hooks/index.ts (1)

10-10: Export of the new useJobSubscriptionsSetup hook looks good.

This addition follows the established pattern for exporting hooks in this file and will make the new hook accessible to other components.

ui/src/types/gisTypes/geoJSON/index.ts (1)

1-1: Appropriate export for GeoJSON Polygon types.

This export statement follows the proper pattern for barrel files, making all polygon-related types available through this index file, which improves organization and accessibility of these types.

ui/src/features/Editor/components/OverlayUI/components/index.ts (1)

9-9: Export of new DebugPreview component looks good.

This addition follows the established pattern for exporting components in this file, making the new debug preview functionality accessible to other parts of the application.

ui/src/components/TextArea/index.tsx (1)

12-12: Changing max-height from relative to absolute units.

The max-height has been changed from what appears to be a viewport-relative unit (likely 15vh) to a fixed pixel value (300px). This will make the component's maximum height consistent across different viewport sizes.

Consider verifying that this change doesn't negatively impact the responsiveness of the TextArea component in various contexts where it's used throughout the application, especially on smaller screens.

ui/src/features/Editor/components/OverlayUI/components/DebugLogs/hooks.ts (1)

25-25: Improved state update pattern using functional form.

The change to use a functional update with setExpanded((prev) => !prev) is a good improvement. It ensures that the expanded state is always toggled correctly based on its previous value, regardless of any other state changes that might happen within the component.

ui/src/features/Editor/components/OverlayUI/components/CanvasActionbar/index.tsx (1)

23-23: Added pointer-events-auto and removed margin.

Replacing m-1 with pointer-events-auto changes two aspects of this component:

  1. It enables pointer events on this element, ensuring it will respond to user interactions
  2. It removes the margin that was previously applied, which may affect alignment

This change is likely part of ensuring the debug preview's UI components remain interactive when overlaid on other elements.

ui/src/types/gisTypes/geoJSON/Polygon.ts (1)

1-8: Well-structured GeoJSON Polygon type definitions.

These type definitions for GeoJSON Polygon structures follow the GeoJSON specification correctly. The use of a separate import for the base Coordinate type promotes code reuse and consistency throughout the application.

A few things to consider:

  1. You might want to add JSDoc comments to explain the GeoJSON structure requirements (e.g., first and last coordinates should be identical in a valid polygon ring)
  2. Consider adding validation functions or utility methods if these types will be manipulated by user input
ui/src/features/Editor/components/OverlayUI/components/LayoutOptionsDialog/index.tsx (2)

1-1: Added memo import for component optimization.

Adding the memo import is appropriate for the performance optimization being implemented.


120-120: Optimized component with React.memo.

Wrapping the component with memo is a good performance optimization that will prevent unnecessary re-renders when props haven't changed. This is particularly valuable for dialog components that may contain complex UI elements but don't need to update frequently.

ui/src/features/Editor/components/OverlayUI/index.tsx (2)

21-21: Good addition of DebugPreview to imports

The addition of the DebugPreview component to the imports is necessary for the UI enhancement.


117-120: LGTM! Nice positioning of debug components

The changes to the div's classes and the addition of DebugPreview alongside CanvasActionBar are well structured. The flex-row-reverse layout ensures proper alignment, and the pointer-events-none/gap styling provides a clean separation between the elements.

ui/src/features/Editor/components/OverlayUI/components/DebugLogs/index.tsx (2)

16-16: Improved height responsiveness

The height adjustments for the debug logs panel provide better visual space allocation. Increasing the default height from 300px to 350px offers more viewable content, and using 80vh for the expanded state ensures better responsiveness across different screen sizes.


26-36: Enhanced UI controls for state visualization

The improved conditional rendering of minimize/expand controls provides clearer visual feedback about the component's state. The separation of concerns between minimization and expansion makes the UI more intuitive.

ui/src/features/Editor/components/OverlayUI/components/NodePickerDialog/index.tsx (2)

1-1: Good addition of memo import

Adding memo from React is a good preparation for the performance optimization at the export.


76-76: Good performance optimization with memo

Wrapping the NodePickerDialog component with memo is a good performance optimization that prevents unnecessary re-renders when the props haven't changed. This is especially beneficial for dialog components that may be conditionally rendered based on user interactions.

ui/src/components/Select/index.tsx (2)

33-33: Prevent icon shrinking

The addition of shrink-0 to the CaretSortIcon prevents the icon from shrinking when space is constrained, ensuring consistent visibility of the dropdown indicator.


80-80: Background class change

Changed background from bg-popover to bg-card, which adjusts the styling to match the card component design system. This creates more visual consistency with other card-like elements in the application.

ui/src/features/Editor/components/BottomBar/index.tsx (2)

28-28: Simplified hooks usage

The component has been refactored to only destructure jobStatus from useHooks(), removing isOpen and onOpen properties. This simplifies the component's dependencies and narrows its focus to displaying job status.


45-56: Direct status reference

Changed from using debugJob?.status to directly using jobStatus in conditional expressions. This simplifies the code by removing optional chaining and makes the status checking more direct.

ui/src/lib/i18n/locales/en.json (1)

92-95:

❓ Verification inconclusive

Added localization strings for debug preview feature

New strings have been added to support the debug preview functionality, including data selection, output data identification, and viewer type options. These translations should be verified to ensure they properly convey the intended meaning and should be completed for all supported languages.

Would you like me to verify if these strings have been added to all other language files as well?


🏁 Script executed:

#!/bin/bash
# Check if the new strings exist in all language files
echo "Checking for new strings across all language files:"
grep -r "Select Data to Preview\|Data Viewer\|3D Viewer" ui/src/lib/i18n/locales/

Length of output: 1120


Localization strings for debug preview verified – review " (Output data)" key

  • The new strings "Select Data to Preview", "Data Viewer", and "3D Viewer" are present in all language files. In Spanish and Japanese the translations are provided, whereas the English, French, and Chinese locales still have empty values.
  • Note that the " (Output data)" key (present in the English file) wasn’t included in the initial grep check. Please confirm if this key should also have localized values in all languages.
ui/src/features/Editor/components/LeftPanel/index.tsx (1)

30-31:

✅ Verification successful

Updated props interface

Two significant changes to the component interface:

  1. Added optional selected property of type Node to directly access the selected node's data
  2. Removed "bottom" from the onOpen function parameter options, limiting panel control to only "left" and "right"

These changes suggest an architectural shift in how the UI panels are managed, particularly removing direct control of the bottom panel from this component.

Verify if the removal of "bottom" from panel options is intentional and consistent across the codebase:


🏁 Script executed:

#!/bin/bash
# Check for any remaining references to opening a "bottom" panel
echo "Searching for references to 'bottom' panel in the codebase:"
rg -A 2 -B 2 'onOpen\(\s*["\']bottom["\']' ./ui/src/

Length of output: 251


Action Required: Confirm Consistent Removal of "bottom" Option

The updated interface now only allows "left" or "right" for the onOpen function, with the "bottom" option removed. A revised search using a corrected regex did not yield any occurrences of the "bottom" panel option within the ./ui/src/ directory. This suggests that the removal is intentional and consistent.

  • Verify manually that there are no edge-case references (e.g., indirect references or dynamically constructed strings) to the "bottom" panel option.
  • Ensure that the architectural shift implied by this change fully aligns with the new UI panel management strategy.

---

🏁 Script executed:

```shell

#!/bin/bash
echo "Re-checking references to 'bottom' panel in the codebase (corrected regex):"
rg -A 2 -B 2 "onOpen\(\s*['\"]bottom['\"]" ./ui/src/

Length of output: 347


Interface Update Verified: Removal of "bottom" Option Confirmed

The updated props interface now includes an optional selected property (Node) and restricts the onOpen function to only "left" and "right" options. A re-run with a corrected regex search across the UI codebase produced no references to an "onOpen" call with "bottom", which suggests that the removal is intentional and consistent.

  • File Verified: ui/src/features/Editor/components/LeftPanel/index.tsx
  • Change Confirmation:
    • Added selected?: Node for direct access to the selected node's data.
    • Removed "bottom" from the permissible options in onOpen, aligning panel management with the new architectural strategy.
  • Action: Please perform a manual review for any indirect or dynamic references to "bottom" if needed.
ui/src/features/Editor/components/OverlayUI/components/DebugPreview/components/DataTable/index.tsx (2)

1-30: Well-structured component for displaying data in tabular format

This DataTable component is well implemented with clean prop handling and layout. It properly utilizes the useDataColumnizer hook to process data and wraps the underlying Table component with appropriate styling.

A few notes:

  • The component handles null values for both fileContent and fileType in props
  • The overflow-scroll CSS class ensures large datasets remain viewable
  • The component includes features like condensed display, column selection, and filtering

10-14: Consider adding error handling for useDataColumnizer

The hook is receiving potentially null values, but there's no visible error handling if the hook fails to process the data properly.

Consider adding error state handling, such as:

const DataTable: React.FC<Props> = ({ fileContent, fileType }) => {
+  const [error, setError] = useState<string | null>(null);
  const { tableData, tableColumns } = useDataColumnizer({
    parsedData: fileContent,
    type: fileType,
  });

+  if (error) {
+    return <div className="p-4 text-red-500">{error}</div>;
+  }
ui/src/features/Editor/useUIState.ts (2)

72-74: UI layout change: bottom panel option removed

The openPanel state no longer accepts "bottom" as a value, indicating that the bottom panel has been either removed or is being handled by a different mechanism in the UI.


76-77:

❓ Verification inconclusive

Updated handlePanelOpen function signature for consistency

The parameter type for handlePanelOpen has been appropriately updated to match the state changes, removing "bottom" as an option.

Please verify that all components using handlePanelOpen have been updated to no longer pass "bottom" as a parameter:


🏁 Script executed:

#!/bin/bash
# Search for any remaining references to "bottom" panel
rg -A 5 -B 5 "handlePanelOpen\(.+bottom" --glob "*.tsx" --glob "*.ts"

Length of output: 71


Action Required: Confirm Removal of "bottom" from handlePanelOpen Usage

The updated signature in ui/src/features/Editor/useUIState.ts (lines 76–77) now accepts only "left" or "right" as valid parameters. Our initial automated search did not return any references passing "bottom" to handlePanelOpen, but the lack of output raises low-confidence in this automated check. Please perform a manual verification to ensure that no component is still invoking handlePanelOpen with "bottom".

  • Location: ui/src/features/Editor/useUIState.ts, Lines 76–77
ui/src/features/WorkspaceJobs/components/JobDetails/index.tsx (4)

6-6: Added access token handling for job subscriptions

You've correctly updated the component to support authentication for job subscriptions through the accessToken prop.

Also applies to: 11-14


16-20: New subscription management pattern implemented

The component now properly uses the useJobSubscriptionsSetup hook with the accessToken and jobId to establish subscription connections.


32-37: Updated conditional rendering to use new jobStatus variable

The conditional rendering for the cancel button has been correctly updated to use the new jobStatus variable.


21-23:

❓ Verification inconclusive

Renamed status variable for better clarity

The change from statusValue to jobStatus improves code readability and makes the variable name more descriptive of its purpose.

Consider also passing the accessToken to useHooks if it needs it for API calls:


🏁 Script executed:

#!/bin/bash
# Check if useHooks is making any API calls that might need authentication
ast-grep --pattern "useHooks" -- "./ui/src/features/WorkspaceJobs/components/JobDetails/hooks.ts"

Length of output: 95


Clarify API Authentication Requirements for useHooks

The rename from statusValue to jobStatus is clear and enhances readability. However, please verify whether useHooks in ui/src/features/WorkspaceJobs/components/JobDetails/hooks.ts requires an accessToken for any API calls. If your hook implementation does need authentication, update its invocation accordingly. For example:

const { job, details, jobStatus, handleBack, handleCancelJob } = useHooks({
  jobId,
  // Optionally add accessToken if required for API calls:
  // accessToken,
});
  • Action Required:
    • Manually check the implementation of useHooks to confirm if it handles authenticated API calls that need the accessToken.
ui/src/lib/gql/subscriptions/useSubscription.ts (2)

1-21: New subscription hook implementation with React Query

This new hook provides a clean interface for subscription data management using React Query's caching capabilities. The approach of using queryKey for subscription identification and setting infinite cache/stale times is well-suited for real-time data.


15-15:

❓ Verification inconclusive

Empty query function - is data being set externally?

The queryFn returns undefined, which means the hook doesn't fetch data itself. This suggests that the data is being set externally, possibly through WebSockets or another mechanism.

Verify that there's a corresponding mechanism updating the React Query cache:


🏁 Script executed:

#!/bin/bash
# Look for code that updates React Query cache for subscriptions
rg -A 10 -B 5 "queryClient.*setQueryData.*SubscriptionKeys" --glob "*.ts" --glob "*.tsx"

Length of output: 90


Empty query function – please verify external cache updates

The query function currently returns undefined, which suggests that data should be injected externally (for example, via WebSockets or a similar subscription mechanism). However, our automated search (using the shell script that looked for queryClient.setQueryData(...SubscriptionKeys...)) returned no results. Please manually verify whether an external mechanism (such as a WebSocket subscription) is updating the React Query cache as expected.

ui/src/hooks/useJobSubscriptionsSetup.ts (3)

12-22: Well-structured subscription setup for job status

The implementation correctly sets up a subscription to job status changes using the useSubscriptionSetup hook, with appropriate parameters and data transformation using toJobStatus.


23-59: Good implementation of log subscription with duplicate prevention

The log subscription implementation is well thought out, with:

  • Proper type checking for cached data
  • A mechanism to prevent duplicate logs using a Set of processed IDs
  • Good data transformation and sorting logic

This approach ensures that logs are properly accumulated and sorted chronologically.


61-65: Clean cleanup strategy for jobId changes

The effect to clear processed log IDs when jobId becomes undefined is a good practice to prevent stale data when switching between jobs.

ui/src/lib/i18n/locales/ja.json (1)

92-95: New localization entries for debug preview feature

The added Japanese translations for the debug preview feature appear to be correctly implemented. These translations support the new UI elements related to data previewing/viewing capabilities.

ui/src/routes/workspaces.$workspaceId.jobs_.$jobId.tsx (2)

14-26: Properly implemented authentication token handling

The component now correctly retrieves and manages the access token using React's useState and useEffect hooks. The async pattern for fetching the token is well-implemented.


27-30: Enhanced rendering condition with access token requirement

The component now properly checks for both jobId and accessToken before rendering the JobDetails component, ensuring that authentication is in place before attempting to load job data.

ui/src/hooks/useFetchAndReadData.ts (2)

12-18: Well-structured state management for data fetching

The hook has a good organization of state variables for tracking loading status, errors, file content, and type.


34-39: Clean interface for hook return values

The return object provides a well-organized interface with all necessary data and state information.

ui/src/routes/workspaces.$workspaceId_.projects_.$projectId.lazy.tsx (4)

3-3: Added useMemo import to optimize component rendering.

The addition of useMemo helps optimize the computation of currentDebugJobId by caching its value between renders.


12-16: Enhanced hooks organization and introduced job subscriptions.

The import structure has been updated to include necessary hooks like useJobSubscriptionsSetup which is essential for the debugging feature being implemented.


77-85: Well-implemented debug job ID calculation.

This code properly calculates the current debug job ID by finding the job matching the current project ID in the debug run state. The use of useMemo prevents unnecessary recalculations.


87-87: Setup for job subscriptions with proper dependencies.

Properly integrates the job subscription setup with the access token and current debug job ID. This is essential for receiving real-time updates about the debug job.

ui/src/components/visualizations/Cesium/GeoJson.tsx (3)

1-7: Well-structured component setup with proper typing.

The imports and type definitions are clear and appropriate for the component's purpose. The Props type properly defines the expected GeoJSON data input.


16-40: GeoJSON rendering with proper viewer integration.

The component correctly renders the GeoJSON data and zooms to its entities when loaded. The commented-out styling code indicates future styling options that could be implemented.


43-43: Good use of React.memo for performance optimization.

Wrapping the component with memo prevents unnecessary re-renders when props haven't changed, which is important for performance in visualization components.

ui/src/components/visualizations/Cesium/index.tsx (4)

2-8: Updated imports to support GeoJSON visualization.

The imports have been properly updated to include necessary Cesium components and types, as well as the new GeoJsonData component.


12-23: Enhanced Cesium viewer configuration.

The default Cesium props have been updated to use Columbus View mode and disable the home button, which provides a better initial view for GeoJSON data.


25-30: Properly typed component props.

The component props are well-defined with appropriate types, making the component's interface clear and type-safe.


40-42: Proper conditional rendering of GeoJSON data.

The GeoJsonData component is correctly rendered based on conditions that ensure the viewer is loaded and the file type is GeoJSON.

ui/src/features/Editor/components/OverlayUI/components/DebugPreview/hooks.ts (4)

1-7: Well-structured imports for the hook.

The imports are organized clearly, importing standard React hooks and custom hooks needed for the debug preview functionality.


16-21: Efficient debug job ID calculation with useMemo.

Using useMemo for calculating the debug job ID based on the current project is a good optimization. The dependencies array is correctly set up.


47-56: Event handling for UI interactions.

The handlers for expanding, minimizing, and tab changes are well-implemented. The stopPropagation() in handleMinimize is a good practice to prevent event bubbling.


58-69: Clean and organized hook return value.

The hook returns a well-structured object with all the necessary state and handlers, making it easy to use in components.

ui/src/features/LogsConsole/index.tsx (3)

6-6: Good addition of the useSubscription hook

This properly imports the new subscription hook that's being used throughout the codebase.


45-45: Cleaner subscription API usage

The change from using separate variables (isSubscribedRef, stopSubscription) to a simpler API that just returns data improves code maintainability.


112-112: Simplified fetching state logic

The condition for isFetching has been simplified to remove the dependency on isSubscribed.

ui/src/features/WorkspaceJobs/components/JobDetails/hooks.ts (5)

6-6: Good import of the new subscription hook

This properly imports the new subscription hook that's being used throughout the codebase.


54-54: Good fallback to job.status

Using jobStatus || job.status ensures there's always a value displayed, even if the subscription hasn't returned data yet.


78-78: Updated dependencies correctly

The dependencies array has been correctly updated to include jobStatus instead of the removed statusValue.


83-83: Updated return value correctly

The return object now includes jobStatus instead of the previous statusValue, maintaining consistency with the changes made.


16-16:

❓ Verification inconclusive

Missing error handling for job status

The previous implementation likely included error handling through the error state from the hook. Now that you're using useSubscription which only provides data, there's no error handling for failed subscription requests.

Consider adding error handling to provide feedback if the job status subscription fails:


🏁 Script executed:

#!/bin/bash
# Check if the useSubscription hook handles errors internally
rg -A 10 "export const useSubscription" ui/src/lib/gql/subscriptions/useSubscription.ts

Length of output: 89


Missing error handling for job status subscription
Our initial check on useSubscription in ui/src/lib/gql/subscriptions/useSubscription.ts did not reveal any evidence that error handling is managed internally. Please verify that this hook indeed does not expose an error state as part of its return. If error handling is missing, consider implementing one either by updating the hook to return an error state or handling errors explicitly in the component.

  • Action Items:
    • Confirm whether useSubscription incorporates any internal error handling (e.g., by reviewing its implementation or manual verification).
    • If lacking, update the component to react appropriately to subscription failures, ensuring that users receive meaningful feedback in case of an error.
ui/src/features/Editor/components/BottomBar/hooks.tsx (4)

1-3: Simplified imports

The imports have been reduced to only what's necessary after removing several hooks, making the code more maintainable.


19-22: Good implementation of job status subscription

The useSubscription hook is properly used with the correct parameters for tracking job status.


24-26:

❓ Verification inconclusive

Simplified return object

The return object has been simplified to only include jobStatus. Verify that any components using this hook are updated to handle this change.


🏁 Script executed:

#!/bin/bash
# Check how the return value is being used in components
rg -A 5 "useBottomBar\(\)" ui/src/

Length of output: 36


Action: Manually verify hook consumers for updates

The hook in ui/src/features/Editor/components/BottomBar/hooks.tsx now returns only jobStatus. Our automated search (using rg -A 5 "useBottomBar()" ui/src/) didn’t return any usage, which makes it inconclusive whether components elsewhere depend on removed properties. Please perform a manual review to ensure that any consumers of this hook are updated to work with the simplified return object.


7-7:

❓ Verification inconclusive

Simplified function signature

The exported function no longer accepts props, making it more straightforward. Make sure this doesn't break any existing functionality.


🏁 Script executed:

#!/bin/bash
# Check where this hook is being used to ensure the prop removal doesn't cause issues
rg -A 3 "import useBottomBar" ui/src/

Length of output: 39


Below is a new shell script that will search more broadly for any usage of useBottomBar (including invocations with a parenthesis) in the entire ui directory. This can help us confirm whether any code still relies on the hook receiving props:

Once these commands run, please review the output. If no usages are found, it suggests that the hook’s simplified signature (i.e. not accepting any props) isn’t breaking any direct dependencies. However, since the initial search produced no output and we couldn’t conclusively verify that no indirect usage exists, I recommend a manual verification to be extra sure.


Simplified Function Signature – Please Verify Usage
The updated hook in ui/src/features/Editor/components/BottomBar/hooks.tsx now has a simplified signature with no props. Our search (including the newly suggested script) hasn’t revealed any direct usage of useBottomBar that might pass props. Please manually review any indirect or dynamic usage in your environment to confirm that this change is safe.

  • Verified file: ui/src/features/Editor/components/BottomBar/hooks.tsx (simplified export signature)
  • No direct references were found with the automated search

🏁 Script executed:

#!/bin/bash
echo "Searching for usage of 'useBottomBar(' in ui/src..."
rg -F "useBottomBar(" ui/src/

echo "Also checking for any mention of 'useBottomBar' in ui/src..."
rg -F "useBottomBar" ui/src/

Length of output: 438


Simplified Function Signature – Please Manually Verify Usage

The hook in
ui/src/features/Editor/components/BottomBar/hooks.tsx
has been updated to no longer accept props. Our automated searches (using searches for both "useBottomBar(" and "useBottomBar") didn’t yield any direct usage where props are passed. However, the search output was inconclusive, so please perform a manual verification (especially for any dynamic or indirect usages) to ensure that this change won’t break any existing functionality.

  • Affected file: ui/src/features/Editor/components/BottomBar/hooks.tsx (export now simplified)
  • Automated searches did not reveal any direct usages passing props, but manual review is advised.
ui/src/utils/fetchAndReadGeoData.ts (3)

1-1: Good type definition for supported data types

Explicitly defining the supported data types as a union type allows for easy extension in the future.


8-10: Good input validation

The function properly checks if the URL is empty and returns an appropriate error message.


34-39: Good error handling

The error handling is comprehensive, extracting the error message appropriately whether it's an Error object or something else.

ui/src/features/Editor/components/OverlayUI/components/DebugPreview/index.tsx (1)

101-102: Consider performance optimization for long data tables.

The current implementation places all content in an overflow scroll, which could lead to performance issues with large datasets.

Consider implementing virtualization for better performance with large datasets. You can use libraries like react-window or react-virtualized for this purpose.

ui/src/lib/i18n/locales/fr.json (1)

92-95: Add French translations for new UI strings.

The new strings added for the debug preview feature don't have French translations yet.

Consider adding proper French translations for these new UI strings to maintain a consistent multilingual experience:

-  "Select Data to Preview": "",
-  " (Output data)": "",
-  "Data Viewer": "",
-  "3D Viewer": "",
+  "Select Data to Preview": "Sélectionner les données à prévisualiser",
+  " (Output data)": " (Données de sortie)",
+  "Data Viewer": "Visualiseur de données",
+  "3D Viewer": "Visualiseur 3D",

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

🧹 Nitpick comments (4)
ui/src/hooks/useFetchAndReadData.ts (2)

19-32: Consider adding cleanup for async operations

There's a potential memory leak if the component unmounts before the async operation completes. Consider adding a cleanup function.

 useEffect(() => {
+  let isMounted = true;
   if (!fileContent || dataUrl !== prevDataUrl.current) {
     setIsLoading(true);
     setError(null);
     (async () => {
       const { fileContent, type, error } = await fetchAndReadData(dataUrl);
+      if (isMounted) {
         setFileContent(fileContent);
         setFileType(type);
         setError(error);
         setIsLoading(false);
+      }
     })();
     prevDataUrl.current = dataUrl;
   }
+  return () => {
+    isMounted = false;
+  };
 }, [dataUrl, fileContent]);

12-40: Consider naming the hook function

For better debugging and stack traces, consider naming the hook function rather than using an anonymous function.

-export default ({ dataUrl = "" }: Props) => {
+export default function useFetchAndReadData({ dataUrl = "" }: Props) {
  const prevDataUrl = useRef<string | null>(null);
  // Rest of the code...
  return {
    fileContent,
    fileType,
    isLoading,
    error,
  };
-};
+}
ui/src/features/Editor/components/OverlayUI/components/DebugPreview/index.tsx (2)

43-43: Consider extracting complex className logic

The className string is quite complex with conditional classes. Consider extracting this to a variable for better readability.

+ const containerClass = `pointer-events-auto w-[45vw] min-w-[700px] rounded border bg-secondary transition-all ${
+   minimized ? "h-[36px]" : expanded ? "h-[85vh] w-[90vw]" : "h-[500px]"
+ }`;

  return outputURLs ? (
    <Tabs
-      className={`pointer-events-auto w-[45vw] min-w-[700px] rounded border bg-secondary transition-all ${minimized ? "h-[36px]" : expanded ? "h-[85vh] w-[90vw]" : "h-[500px]"}`}
+      className={containerClass}
      defaultValue="data-viewer">

101-101: Consider using overflow-auto instead of overflow-scroll

Using overflow-auto instead of overflow-scroll would display scrollbars only when needed, providing a better user experience.

      <TabsContent
-        className="h-[calc(100%-35px)] overflow-scroll"
+        className="h-[calc(100%-35px)] overflow-auto"
        value="data-viewer">
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 02c2669 and 21f0aa6.

📒 Files selected for processing (5)
  • ui/src/features/Editor/components/OverlayUI/components/DebugPreview/components/GeoMap/index.tsx (1 hunks)
  • ui/src/features/Editor/components/OverlayUI/components/DebugPreview/components/index.ts (1 hunks)
  • ui/src/features/Editor/components/OverlayUI/components/DebugPreview/index.tsx (1 hunks)
  • ui/src/features/LogsConsole/index.tsx (3 hunks)
  • ui/src/hooks/useFetchAndReadData.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • ui/src/features/Editor/components/OverlayUI/components/DebugPreview/components/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • ui/src/features/LogsConsole/index.tsx
🔇 Additional comments (5)
ui/src/features/Editor/components/OverlayUI/components/DebugPreview/components/GeoMap/index.tsx (1)

1-18: Clean implementation of GeoMap component

This component provides a simple and effective wrapper for the CesiumViewer, properly handling the props and styling. The structure is clean and straightforward.

ui/src/hooks/useFetchAndReadData.ts (2)

19-32: Good fix on loading state management

The loading state is now correctly set to false after the async operation completes, fixing the issue identified in a previous review.


19-32: Reconsider dependency on fileContent

Including fileContent in the dependency array might cause unnecessary re-fetching if fileContent changes externally. Consider if this is actually needed, or if dataUrl is the only dependency you need to trigger a fetch.

ui/src/features/Editor/components/OverlayUI/components/DebugPreview/index.tsx (2)

24-24: Good job fixing the Map import name

The component is now correctly imported as GeoMap, avoiding shadowing the global Map object.


41-109: Well-structured UI component with good separation of concerns

The component is well-organized, with clear separation between the UI elements and the business logic (which is extracted to the custom hook). The use of tabs, selectors, and state for minimizing/expanding provides a good user experience.

@KaWaite KaWaite merged commit 4d8f259 into main Mar 14, 2025
23 checks passed
@KaWaite KaWaite deleted the ui/debug-preview branch March 14, 2025 01:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant