From 262fbcd89dba0c85b9bd95059fe8385aebcf3e90 Mon Sep 17 00:00:00 2001 From: Ivan <45982459+ivntsng@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:06:59 -0800 Subject: [PATCH] implement feature flags and improve UI consistency (#601) * implement feature flags and improve UI consistency * Additional updates to robot-hub * Additional updates & resolved upload images bug --- .../listing/ListingFeatureButton.tsx | 2 +- .../listing/ListingRegisterRobot.tsx | 9 +- .../components/modals/DeleteRobotModal.tsx | 10 +- .../components/modals/RegisterRobotModal.tsx | 10 +- frontend/src/components/nav/Navbar.tsx | 20 +-- frontend/src/components/nav/navigation.tsx | 2 +- frontend/src/components/pages/Profile.tsx | 38 +++--- frontend/src/components/pages/Terminal.tsx | 27 +++- .../src/components/terminal/RobotCard.tsx | 47 ++++--- .../terminal/TerminalRobotModel.tsx | 2 +- .../terminal/TerminalSingleRobot.tsx | 119 ++++++++++++------ frontend/src/lib/utils/featureFlags.ts | 7 ++ store/app/crud/base.py | 11 +- 13 files changed, 195 insertions(+), 109 deletions(-) create mode 100644 frontend/src/lib/utils/featureFlags.ts diff --git a/frontend/src/components/listing/ListingFeatureButton.tsx b/frontend/src/components/listing/ListingFeatureButton.tsx index 74d3d399..8c634b72 100644 --- a/frontend/src/components/listing/ListingFeatureButton.tsx +++ b/frontend/src/components/listing/ListingFeatureButton.tsx @@ -72,7 +72,7 @@ const ListingFeatureButton = (props: Props) => {

diff --git a/frontend/src/components/modals/DeleteRobotModal.tsx b/frontend/src/components/modals/DeleteRobotModal.tsx index 760cedbc..cc764af8 100644 --- a/frontend/src/components/modals/DeleteRobotModal.tsx +++ b/frontend/src/components/modals/DeleteRobotModal.tsx @@ -53,19 +53,19 @@ export function DeleteRobotModal({ return (

- + Delete Robot - +
Are you sure you want to delete robot{" "} - + "{robot.name}" ? This action cannot be undone. - + Data associated with this robot will be deleted and no longer accessible. @@ -73,7 +73,7 @@ export function DeleteRobotModal({ {error &&
{error}
} -
+
diff --git a/frontend/src/components/modals/RegisterRobotModal.tsx b/frontend/src/components/modals/RegisterRobotModal.tsx index e4435a80..86b3985b 100644 --- a/frontend/src/components/modals/RegisterRobotModal.tsx +++ b/frontend/src/components/modals/RegisterRobotModal.tsx @@ -69,13 +69,13 @@ export function RegisterRobotModal({ onClose(); }} > - + - Register New Robot + Create New Robot Instance
-
-
-
+
+
{featuredListings?.map((listing) => (
-
+
{isAuthenticated ? ( <>
-

+

Joined on{" "} {user.created_at ? formatJoinDate(user.created_at) @@ -218,7 +213,7 @@ export const RenderProfile = (props: RenderProfileProps) => {

@@ -267,7 +262,7 @@ export const RenderProfile = (props: RenderProfileProps) => { {user.bio ? (

{user.bio}

) : ( -

+

No bio set. Edit your profile to add a bio.

)} @@ -301,7 +296,7 @@ export const RenderProfile = (props: RenderProfileProps) => {
@@ -341,21 +336,22 @@ export const RenderProfile = (props: RenderProfileProps) => { - - Your Bot Listings - - Your Robot Listings + + diff --git a/frontend/src/components/pages/Terminal.tsx b/frontend/src/components/pages/Terminal.tsx index 9e188791..74f46eea 100644 --- a/frontend/src/components/pages/Terminal.tsx +++ b/frontend/src/components/pages/Terminal.tsx @@ -8,6 +8,7 @@ import Spinner from "@/components/ui/Spinner"; import { useAlertQueue } from "@/hooks/useAlertQueue"; import { useAuthentication } from "@/hooks/useAuth"; import ROUTES from "@/lib/types/routes"; +import { FEATURE_FLAGS } from "@/lib/utils/featureFlags"; import RequireAuthentication from "../auth/RequireAuthentication"; @@ -49,7 +50,21 @@ const TerminalInner = () => { if (error) { addErrorAlert(error); } else { - setRobots(data.robots); + if (FEATURE_FLAGS.DEMO_ROBOT_ENABLED && data.robots.length === 0) { + const demoRobot: SingleRobotResponse = { + robot_id: "d38afe50c9d6b936", + name: "K-Scale Demo", + description: "Click on the robot name to start the demo!", + listing_id: "3f26c2bc2c072f50", + user_id: "", + username: "K-Scale", + slug: "demo", + created_at: Date.now() / 1000, + }; + setRobots([demoRobot]); + } else { + setRobots(data.robots); + } } } catch (error) { addErrorAlert(error); @@ -61,6 +76,11 @@ const TerminalInner = () => { }, [api, currentUser, isAuthenticated]); const handleDeleteRobot = async (robotId: string) => { + if (FEATURE_FLAGS.DEMO_ROBOT_ENABLED && robotId === "3688c9a4af0b58e1") { + addErrorAlert("Demo robot cannot be deleted"); + return; + } + try { const { error } = await api.client.DELETE("/robots/delete/{robot_id}", { params: { @@ -92,6 +112,11 @@ const TerminalInner = () => { robotId: string, updates: { name?: string; description?: string }, ) => { + if (FEATURE_FLAGS.DEMO_ROBOT_ENABLED && robotId === "3688c9a4af0b58e1") { + addErrorAlert("Demo robot cannot be modified"); + return; + } + try { const { error } = await api.client.PUT("/robots/update/{robot_id}", { params: { diff --git a/frontend/src/components/terminal/RobotCard.tsx b/frontend/src/components/terminal/RobotCard.tsx index 6a469c6d..2d785e5c 100644 --- a/frontend/src/components/terminal/RobotCard.tsx +++ b/frontend/src/components/terminal/RobotCard.tsx @@ -6,6 +6,7 @@ import { SingleRobotResponse } from "@/components/terminal/types"; import { Card } from "@/components/ui/Card"; import { Button } from "@/components/ui/button"; import ROUTES from "@/lib/types/routes"; +import { FEATURE_FLAGS } from "@/lib/utils/featureFlags"; import { formatDate } from "@/lib/utils/formatDate"; import { DeleteRobotModal } from "../modals/DeleteRobotModal"; @@ -19,6 +20,9 @@ interface RobotCardProps { export default function RobotCard({ robot, onDeleteRobot }: RobotCardProps) { const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); + const isDemo = + FEATURE_FLAGS.DEMO_ROBOT_ENABLED && robot.robot_id === "3688c9a4af0b58e1"; + return (
@@ -36,11 +40,14 @@ export default function RobotCard({ robot, onDeleteRobot }: RobotCardProps) {
- + - -
+ {/* Connection controls - Only show if ROBOT_STREAMING is enabled */} + {FEATURE_FLAGS.ROBOT_STREAMING && ( +
+ + +
+ )} {/* Main grid layout */}
- {/* Video and Audio feed panel */} -
-
- {/* Video container */} -
-
- Waiting for video connection... + {FEATURE_FLAGS.ROBOT_STREAMING ? ( + <> + {/* Video and Audio feed panel */} +
+
+ {/* Video container */} +
+
+ Waiting for video connection... +
+
+ + {/* Audio indicator */} +
+
+ +
+
+
+
+
- {/* Audio indicator */} -
-
- -
-
-
-
+ {/* 3D Mesh Visualization panel */} +
+
+ + ) : ( + // When streaming is disabled, 3D viewer takes full width and combined height +
+
-
- - {/* 3D Mesh Visualization panel */} -
- -
+ )} {/* Klang Input panel */}
-